Vue 实现数组四级联动

前言
最近项目上有个需求就是做下拉列表的四级联动,使用的是vuejs + elementui,使用数组存储对象的形式做为列表渲染到页面上的数据,但是在下拉列表联动的时候发现几个问题,现在记录下解决办法,分享给大家。
修改对象数组后前端页面不重新渲染
查看或者编辑回显数据时,联动数据渲染出错(只显示key,不显示name)

关于复杂数据处理
之前在写React的时候,复杂一点的数据会通过Immutable.js来实现,通过get和set来实现数据的设置和读取,以及深层拷贝等功能,现在到了Vue发现数据复杂一点就不知道如何处理,第三方关于vue的immutable.js框架也没有了解过,后面有时间可以关注并学习下(大家有使用过的可以分享给我)。
四级联动问题解决方法
问题一:修改对象数组后前端页面不重新渲染 
Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
举个例子:
var vm = new Vue({
   data: {
     items: ['a', 'b', 'c']
   }
 })
vm.items[1] = 'x' // 不是响应性的 
vm.items.length = 2 // 不是响应性的
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将在响应式系统内触发状态更新:
// Vue.set
 Vue.set(vm.items, indexOfItem, newValue)
 // Array.prototype.splice
 vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名: 
 vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice: 
 vm.items.splice(newLength)
Vue.set(vm.items, indexOfItem, newValue),下面就演示个例子:export default {
    data(){
        return {
            arrys :[
                {
                    one: '',
                    oneList: Promise: getOneList(),
                    two: '',
                    twoList: Promise: getTwoList(one),
                    three: '',
                    threeList: Promise: getThreeList(two),
                    four: '',
                    fourList: Promise: getFourList(three),
                }
            ]
        }
    },
    methods: {
        // one下拉列表change事件
        oneChange(key, index){
            this.getTwoList(key).then(res => {
            this.arrys.forEach((item, i) => {
              if (i === index) {
                // 因为是四级联动,所以change one之后,two、three和four都要置空
                let newitem = {
                  two: [],
                  twoList: res,
                  three: '',
                  four: '',
                  threeList: [],
                  fourList: []
                }
                // 说明:修改arrys中第i个的数据,只有使用Vue.set页面才会重新渲染
                // newitem会覆盖item中的数据,并生成一个新的引用指针
                Vue.set(this.arrys, i, Object.assign({}, item, newitem))
              }
            })
          });
        },
        // two下拉列表change事件
        twoChange(key, index){
            
        },
        // three下拉列表change事件
        threeChange(key, index){
            
        },
        // four下拉列表change事件
        fourChange(key, index){
            
        },
        // 获取one 列表
        getOneList(){
            
        },
        // 获取two 列表
        getTwoList(oneKey){
            
        },
        // 获取three 列表
        getThreeList(twoKey){
            
        },
        // 获取four 列表
        getFourList(threeKey){
            
        }
    }
    
}
问题二:查看或者编辑回显数据时,联动数据渲染出错(只显示key,不显示name)
// 假设res是后台返回的要渲染到页面上的四级联动数组数据
let resdata = res;
// 给one、two、three和four赋值
resdata.forEach(item => {
    this.arrys.push({
        one: item.one,
        two: item.two,
        three: item.three,
        four: item.four
    })
})
// 获取twoList(说明:因为oneList是首级,所以直接获取就好,这里就不展示代码了)
Promise.all(resdata.map(item => this.getTwoList(item.one)))
    .then(twoListData => {
    
        twoListData.forEach((data, i) => {
            
            this.arrys[i].twoList = data;
    
        })
})
  
// promise获取threeList列表
Promise.all(resdata.map(item => this.getThreeList(item.two)))
  .then(threeListData => {
  
        threeListData.forEach((data, i) => {
        
            this.arrys[i].threeList = data;
            
        })
  })
  
// promise获取fourList列表
Promise.all(resdata.map(item => this.getFourList(item.three)))
  .then(fourListData => {
  
        fourListData.forEach((data, i) => {
        
            this.arrys[i].fourList = data;
            
        })
  })
总结
逆锋起笔是一个专注于程序员圈子的技术平台,你可以收获最新技术动态、最新内测资格、BAT等大厂大佬的经验、增长自身、学习资料、职业路线、赚钱思维,微信搜索逆锋起笔关注!
评论
