当前位置: 首页 > Web前端 > vue.js

vue实现数组四级联动

时间:2023-03-31 15:06:29 vue.js

前言最近有个项目需求做下拉列表的四级联动,使用vuejs+elementui,使用数组存储对象的形式作为列表在页面上渲染数据,但是在链接下拉列表的时候发现了几个问题,现把解决办法记录下来分享给大家。修改对象数组后,查看或编辑回显数据时前端页面不重新渲染,联动数据渲染错误(只显示key,不显示name)关于复杂数据处理之前写React时,复杂的数据会通过Immutable.js来实现,通过get和set实现数据的设置和读取,以及深拷贝等功能,现在Vue发现数据很复杂不知道怎么处理,以及第三方没有学习过vue的immutable.js框架。有空可以关注学习(用过的可以分享给我)。四级联动问题解决问题一:修改对象数组后,前端页面没有重新渲染。其实Vue官网也解释了数组变化时页面不会重新渲染的问题。Vue无法检测到以下数组的更改:当您直接使用索引设置数组项时,例如:vm.items[indexOfItem]=newValue当您修改数组的长度时,例如:vm.items.length=newLength例如:varvm=newVue({data:{items:['a','b','c']}})vm.items[1]='x'//不响应vm.items.length=2//Notresponsive为了解决第一类问题,下面两种方法可以达到和vm.items[indexOfItem]=newValue一样的效果,同样会在响应式系统中触发状态更新://Vue.setVue.set(vm.items,indexOfItem,newValue)//Array.prototype.splicevm.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),这里是一个例子:一),三:'',threeList:承诺:getThreeList(二),four:'',fourList:Promise:getFourList(three),}]}},methods:{//一个下拉列表改变事件oneChange(key,index){this.getTwoList(key).then(res=>{this.arrys.forEach((item,i)=>{if(i===index){//因为是四级联动,改变后一二三四必须为空letnewitem={two:[],twoList:res,three:'',four:'',threeList:[],fourList:[]}//解释:修改arrys中的第i个数据,页面会重新仅在使用Vue.set时渲染//newitem会覆盖item中的数据并生成新的引用指针Vue.set(this.arrys,i,Object.assign({},item,newitem))}})});},//二下拉列表变化事件twoChange(key,index){},//三下拉列表变化事件三Change(key,index){},//四个下拉列表变化事件fourChange(key,index){},//获取一个列表getOneList(){},//获取两个列表getTwoList(oneKey){},//获取三级列表getThreeList(twoKey){},//获取四级列表getFourList(threeKey){}}}根据以上代码,可以实现四级联动,页面变化时动态渲染,从而完成联动效果和修改对象数组后前端页面不重新渲染。问题2:查看或编辑回显数据时,联动数据渲染错误(只显示key,不显示name)问题是这样的:我们保存后台数据一二三四,而oneList,twoList,threeList和fourList不需要保存(通过另外一个接口获取,每次打开都会调用),然后我们查看编辑最后一个四级联动的时候,发现下拉列表中有一个,两个、三和四只显示密钥,不显示名称。原因是oneList、twoList、threeList、fourList比一、二、三、四数据赋值“慢”,因为它们是异步的,所以当list回调回来的时候,页面已经渲染好了,所以没有成功,于是出现了问题2:只显示了key,没有显示name。那么如何解决这个慢的问题呢?我们可以使用Promise.all来解决。//假设res为后台返回的四级联动数组数据在页面上渲染letresdata=res;//给一、二、三、四赋值resdata.forEach(item=>{this.arrys.push({一:item.one,二:item.two,三:item.three,四: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=数据;})})为什么要写三遍Promise.all?因为forEach异常,无法循环遍历forEach获取Promises给arrys赋值。如果大家有更好的方法,可以提出来,这样就解决了第二个问题。小结1、可能有人会问:为什么不把oneList和twoList设为publiclist,和arrys数组分开,不是更方便阅读吗?答案是:不能,因为是四级联动数组,所以数组中的每个对象都要保存自己的oneList和twoList。想象一下:如果arrys数组中有3条数据,我改变了第一个,那么twoList就会改变,第二个twoList也会随之改变。这不是一个单一的四级联动,而是所有的两个列表都在相应移动!2、el-select只要将key和list分别赋值,就可以显示对应的名字(说明当key赋值时,el-selectlist会找到对应的,如果是则显示namefound)3.怎么办在这个过程中,我发现了一个问题:在更改的时候,我发现二、三、四只显示了key,没有显示名字。后来发现是因为我用的是ht-select,而不是elementUI自带的el-select。改完之后就没问题了,也算是小插曲了。参考学习使用Promise