有一个场景,现在有一个公共的子组件,这个子组件在很多地方都被用到了,现在有个问题,就是从父组件传递过来的数据是一个对象,如下代码所示,因为这个数据是从后台获取的,现在想要把含有value:0的数据过滤掉,于是我开始了下面的写bug之旅。
{
name:"",
colors:["red","black"],
data:[{name:"wer",value:0},{name:"wer",value:1}]
}
子组件用props接受
props: { //数据
pieObject: {
type: Object,
defalut() {
return {};
}
}
},
然后在mounted 中初始化
mounted() {
this.pieObj = this.pieObject;
}
注意为上面的代码后面的bug 埋下了隐患
因为需要去监听传递过来的这个数据的变化,于是我给pieObject添加了监听,同时过滤掉value为0的数据
watch: {
pieObject: {
handler(curVal, oldName) {
//去除空的数据
if (curVal) {
//深克隆curVal,不要直接修改,引起不必要的bug
let obj =_.cloneDeep(curVal)
let newData = obj.data.filter(item => {
return item.value != 0
})
this.pieObj.colors = obj.colors;
this.pieObj.name = obj.name;
this.pieObj.data = newData;
this.draw();
}
},
// immediate: true,
deep: true
}
}
上面的代码没有问题吧,但是程序就一直好想处于死循环一样,经过断点等调试发现,过滤后的data 赋值给pieObj this.pieObj.data = newData;,curVal里的data也改变了,为甚么呢?我不是对他进行深克隆了吗?注意这里是watch监听,curVal什么时候会变,两种情况,我自己显示的修改了他,还有最最最基本的是监听的数据 pieObject 变了,他为什么变了,注意下面的代码
mounted() {
//问题出在这里,pieObject 和 pieObj 指向了同一个对象,复制的只是对象的地址,在watch中 this.pieObj.data = newData;对pieObj进行了新的赋值,那么pieObject的值也变了,变了就会触发watch监听,所以才会出现像上面的死循环一样的问题,所以在这里不能直接赋值,要进行深克隆,bug解决
//this.pieObj = this.pieObject;
this.pieObj = _.cloneDeep(this.pieObject);
}