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等大厂大佬的经验
、增长自身
、学习资料
、职业路线
、赚钱思维
,微信搜索逆锋起笔
关注!
评论