vue父组件传递给子组件的对象的部分元素在子组件中变为undefined
今天遇到个偶现的bug:父组件传递了一个对象给子组件,子组件中使用这个对象中的部分元素变为undefined。问题分析:父组件的这个对象(task)是通过computed侦听http接口返回的数据后被赋值的(这个http接口5s被调用一次),子组件中变为undefined的元素(stageEnv)是在父组件mounted方法中动态赋值的(此前这个对象中未定义此元素):mounted(...
今天遇到个偶现的bug:父组件传递了一个对象给子组件,子组件中使用这个对象中的部分元素变为undefined。
问题分析:
父组件的这个对象(task)是通过computed侦听http接口返回的数据后被赋值的(这个http接口5s被调用一次),子组件中变为undefined的元素(stageEnv)是在父组件mounted方法中动态赋值的(此前这个对象中未定义此元素):
mounted() {
...
if (this.story.stages[this.index]['stageEnv']) {
this.task.stageEnv= this.story.stages[this.index]['stageEnv']
} else {
this.task.stageEnv= ''
}
...
this.taskInfo = this.task // 把task赋值给taskInfo
...
}
taskInfo是最终传递给子组件的对象。
在代码中加了各种log和断点后终于发现问题就出现在了this.taskInfo = this.task这里,在mounted执行结束前,有http接口调用返回导致task被更新,这里taskInfo的赋值使用的是浅拷贝,意味着taskInfo也被刷新了,给它赋的stageEnv也没有了,而它依旧会被继续传递给子组件,就出现了我遇到的问题。
解决方案:
在mounted开始时就使用深拷贝将task的值赋值给task,后续的赋值也直接赋给taskInfo,这样即使task发生了变更,也不影响传递进子组件的数据(但是这里需要注意的是,如果父组件其他地方也使用了mounted中赋值的这个元素,其他地方也需要将this.task.xxx改为this.taskInfo.xxx):
mounted() {
for (const key in this.task) {
this.taskInfo[key] = this.task[key]
}
...
if (this.story.stages[this.index]['stageEnv']) {
this.taskInfo.stageEnv= this.story.stages[this.index]['stageEnv']
} else {
this.taskInfo.stageEnv= ''
}
...
}
总结:
在使用子组件的场景中,如果传递给子组件的对象来自计算属性,且此计算属性监听的数据来自不断定时更新的数据,且传递给子组件前会对此对象的值进行变更,则需要在mounted开始时就使用深拷贝将此对象值拷贝出来,防止在加载子组件的半路上计算属性更新引起值丢失的问题。这几种因素组合在一起简直太巧了~记录一下
更多推荐
所有评论(0)