vue实现 前端处理嵌套数据问题

本文介绍了一个使用Vue实现的三级联动选择器,数据结构为数组嵌套对象再嵌套数组。通过v-for指令遍历多层数据,实现了类似ElementUI级联选择器的功能。在过程中遇到了不同层级数据量不一致导致的错误,解决方案是在切换上级选项时重置二级选项的索引,避免因数据长度差异引发的错误。

我们在开发的时候,有时会遇到类似于三级联动的问题,这时候后端传过来的数据类型为数组包含对象,对象再包含数组,数组再包含对象的层级关系,如下图:
在这里插入图片描述

我们要实现的效果类似elementUI中的级联选择器
如下图:在这里插入图片描述

<template>
  <div class="hello">
    <div class="l div1">
      <div
        v-for="(item , i) in mydata"
        :class="{mycolor : i == num1}"
        @click="nameClick(i)"
      >
        <div>{{item.name}}</div>
      </div>
    </div>
    <div class="l div2">
      <div
        v-for="(item1,a) in mydata[num1].selfinform"
        :class="{mycolor2 : a == num2}"
        @click="div2Click(a)"
      >
        <div>{{item1.age}}</div>
      </div>
    </div>
    <div class="l div3">
      <div v-for="(item2) in mydata[num1].selfinform[num2].otherInner">
        <div>{{item2.Number}}</div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: "HelloWorld",
    methods: {
      nameClick(i) {
        this.num2 = 0;
        this.num1 = i;
        console.log("我是num1的i:" + i);
      },
      div2Click(a) {
        this.num2 = a;
        console.log("我是num2的a:" + a);
      },
    },
    data() {
      return {
        num1: 0,
        num2: 0,
        mydata: [
          {
            name: "指南",
            selfinform: [
              {
                age: "设计原则",
                otherInner: [{ Number: "一致" }, { Number: "反馈" }],
              },
              {
                age: "导航",
                otherInner: [{ Number: "侧向导航" }, { Number: "顶部导航" }],
              },
            ],
          },
          {
            name: "组件",
            selfinform: [
              {
                age: "basic",
                otherInner: [{ Number: "icon图标" }, { Number: "button按钮" }],
              },
              {
                age: "form",
                otherInner: [{ Number: "color色彩" }],
              },
              {
                age: "data",
                otherInner: [{ Number: "typography字体" }],
              },
              {
                age: "notice",
                otherInner: [{ Number: "icon图标" }],
              },
              {
                age: "navigation",
                otherInner: [{ Number: "button按钮" }],
              },
              {
                age: "others",
                otherInner: [{ Number: "Radio单选框" }],
              },
            ],
          },
          {
            name: "资源",
            selfinform: [
              {
                age: "Axure Components",
                otherInner: [{ Number: 1873333333311 }],
              },
              {
                age: "Sketch Templates",
                otherInner: [{ Number: 1560088008811 }],
              },
              {
                age: "组件交互文档",
                otherInner: [{ Number: 18788888888 }],
              },
            ],
          },
        ],
      };
    },
  };
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  * {
    margin: 0;
    padding: 0;
  }
  .div1,
  .div2,
  .div3 {
    border: 1px solid red;
    width: 200px;
  }
  .div1 > div {
    text-align: center;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid black;
    box-sizing: border-box;
  }
  .div2 > div {
    text-align: center;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid black;
    box-sizing: border-box;
  }
  .div3 > div {
    text-align: center;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid black;
    box-sizing: border-box;
  }
  .div2 {
    border: 1px solid green;
  }
  .div3 {
    border: 1px solid blue;
  }
  .l {
    float: left;
  }

  .mycolor {
    background-color: yellow;
  }
  .mycolor2 {
    background-color: cyan;
  }
</style>


最终效果:
在这里插入图片描述

这里我是使用vue实现的这个效果
具体思路:
首先循环第一层数组,将里面的信息输入到第一列,因为循环的时候可以获取到对应的下标,所以我们可以在第二列循环对应下标中的数据,可以先给其默认值num1 :0,num2 : 0,这样的话,初始状态就会直接显示第一行的数据
之后给第一列的标签添加点击事件,当点击之后根据对应的下标动态修改num1的值,点击事件触发时,第二列渲染的数据就会随着num1的改变而改变

注意:
这里我发现一个问题,指南、组件、资源分别对应的第二列 ,第三列的数据量是不同的,如果我们点击组件时,第二列会显示六条数据,我们点击一下其中的others,这时num2的下标就是5,这时,如果我们再点击指南,因为它的第二列只有两条数据,所以会报错
解决方案:
给nameClick(i)的点击事件中添加this.num2 = 0 这样就可以使数据初始化,报错的情况也就消失了

Vue.js 处理前端数据的方式主要依赖于其核心特性:**响应式数据绑定**和**状态管理**。Vue 通过这些机制,使得开发者能够高效地管理数据,并确保视图与数据保持同步。 ### 响应式数据绑定 Vue.js 通过 `Object.defineProperty` 或 `Proxy`(在 Vue 3 中)实现数据的响应式绑定。当数据发生变化时,相关的视图会自动更新,而无需手动操作 DOM。例如,当使用 `v-text` 指令绑定一个变量时,如果该变量的值发生变化,页面上的文本内容也会随之更新 [^3]。这种方式简化了前端开发中的数据操作,使得开发者可以专注于业务逻辑,而不是 DOM 操作。 ```html <div id="app"> <span v-text="msg"></span> </div> <script> new Vue({ data: { msg: "Vue 是一个可爱的框架" } }).$mount("#app"); </script> ``` 在上述代码中,`msg` 是一个响应式数据属性,当它的值发生变化时,页面上 `<span>` 标签的内容会自动更新。 ### 状态管理 对于复杂的应用,Vue 提供了 **Vuex** 作为官方推荐的状态管理模式。Vuex 通过集中管理应用的所有组件的状态,使得状态的变化更加可预测和易于调试。它采用单向数据流的概念,确保状态的变更只能通过提交 **mutations** 来完成,从而避免了直接修状态带来的混乱。 ```javascript // Vuex store 示例 const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { incrementAsync({ commit }) { setTimeout(() => { commit('increment'); }, 1000); } }, getters: { doubleCount(state) { return state.count * 2; } } }); ``` 在组件中,可以通过 `mapState`、`mapMutations`、`mapActions` 和 `mapGetters` 来访问和操作 Vuex 中的状态。这种方式不仅提高了代码的可维护性,还增强了应用的可测试性。 ### 路由管理 Vue 还通过 **Vue Router** 提供了强大的路由管理功能。Vue Router 支持动态路由匹配、嵌套路由、懒加载等功能,能够帮助开发者轻松构建单页应用(SPA)。路由的配置非常简单,只需定义路径和对应的组件即可。 ```javascript // Vue Router 示例 const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = new VueRouter({ routes }); new Vue({ router, el: '#app' }); ``` ### 总结 Vue.js 通过响应式数据绑定和状态管理(如 Vuex)提供了高效的数据处理机制,使得前端开发更加简洁和高效。无论是小型项目还是大型应用,Vue 都能提供合适的解决方案,帮助开发者快速构建高性能的用户界面 [^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值