总结最近遇到的难点,记录下
父页面a,两个兄弟组件b和c
b和c的关联是b页面列表填完数据后,切换到c的时候会调接口处理成另一种格式的列表,并且在c页面会根据某些条件需要填写行内弹窗
需求是当从c切回b的时候,用户填写的行内弹窗的数据还要保留
第一种想法是vuex,把c的列表数据存下来,每次切到b的时候就保存,然后切到c调接口获取c列表数据那里进行比对,根据某个相同的字段或者特定的条件,比如vuex的c列表和调接口获取的c列表的某个字段是唯一的,比如code,然后将vuex里的行内弹窗数据复制给调接口获取的c列表的行内弹窗,考虑到只有单独的页面有这个需求,在vuex中保存有点大材小用,主要是太麻烦
第二种想法是sessionStorage中存下来,然后再取出来用,思路和想法一是一样的,但是数据只会在关闭浏览器的时候才会销毁,也不是很方便,可能还要处理很多bug,也是太麻烦
然后就用了第三种想法,也是同事推荐的,使用深拷贝,确实很好用,思路还是想法一的
在tab切换事件中,我这里使用的是before-leave离开前的钩子函数,因为要做些判断
1/深拷贝数组的方式用了最简单的concat(),还有一种是slice(0)
2/弹窗数据是一个大对象,里面有对象也有数组,如果直接赋值,会拿不到值,用解构赋值…展开对象
3/深拷贝的对象不是c绑定的数组,我这里用的是this.allArr,在接口里获取c数组的时候先赋值给this.allArr数组,虽然c数组没有直接绑定this.allArr,但是数据源是共享的,都双向绑定了,这也是我才知道的,如果一直用c数组赋值再深拷贝,每次切换的时候c数组都会变成最新的,就无法做缓存这个事,最最重要的一个知识点,省去不少麻烦
this.deepAllarr = this.allArr.concat()
<el-tabs type="border-card" :before-leave="confirmLeave" v-model="activeNames">
async confirmLeave(active) {
if (active === 'secondTab') {
let arr = this.tableData//b数组
await this.$refs.costForm.validate(valid => {
if (valid) {
if (arr.length) {
getBySum(obj).then(res => {
if (res && res.code == 200) {
//拿到接口里最新的c数组,第一次切的时候没有深拷贝,拿的就是调接口获取的,当切回明细再切回来的时候就要开始比较了
this.allArr = res.data.all
if (this.deepAllarr.length) {
for (var i = 0; i < this.deepAllarr.length; i++) {
//解构赋值
let exceedObj = { ...this.deepAllarr[i].exceedObj }
let great = { ...this.deepAllarr[i].great }
for (var j = 0; j < this.allArr.length; j++) {
if (
this.allArr[j].Code == this.deepAllarr[i].Code
) {
this.allArr[j].exceedObj = exceedObj
this.allArr[j].great = great
}
}
}
//c数组
this.TotaltableData = this.allArr
}
})
}else {
//在切回明细的时候深拷贝
this.deepAllarr = this.allArr.concat()
}
}})