问题
父组件向子组件传对象,在子组件中向这个对象添加一个新的属性,并将该属性和相应的视图进行绑定,但之后改变该属性的值并没有引起视图的变化,子组件代码如下:
//子组件 test
<template>
<div>
<span>{{ obj.msg }}</span>
</div>
</template>
export default {
data: function() {
return {
obj: Object.assign(this.objProp, {msg: 'hello'})
};
},
props: ['objProp']
};
父组件这样传数据:
//父组件
<test :objProp="obj"></test>
export default {
data: function() {
return {obj: {}}
}
}
可以看到修改该属性并未发生响应式变化:
image.png
原因分析
首先要明确的是父组件的 obj 和子组件的 obj 是同一个对象,这个对象是定义在父组件 data 中的,所以该对象应该由父组件来监听(子组件不监听 obj),然而在父组件定义 obj 的时候并无 msg 这个属性,所以父组件是无法监听到 msg,即 msg 的改变不会引起视图变化。若该对象不定义在 data 中,那么监听权在子组件中。
//父组件
<test :objProp="{}"></test>
或者子组重新创建个新对象,对这个新对象进行监听
//子组件
export default {
data: function() {
return {
obj: Object.assign({}, this.objProp, {msg: 'hello'})
};
},
props: ['objProp']
};
几天后我有了新发现,vue有两种方法添加响应式属性,可以用$set(this.obj, 'flag', true)这个方法来动态添加响应式属性,也可以把原属性和新属性合并到新的对象中this.obj=Object.assign({}, this.obj. {flag: true})