对象属性的响应规则
<body> <div id="root"> {{msg}} </div> </body> <script> var app = new Vue({ el:"#root", data:{ msg:{ a:123, b:{ k:999 } } } }) console.log(app) </script>
运行结果:
可见,vue初始化时创建的getter/setter是递归创建的,不管这个值是否是对象,都会为这个属性创建getter和setter方法。有了这些getter和setter方法,直接执行:
app.msg.b = 999; app.msg.a = 9990; app.msg[‘a‘] = 999; app.msg = {xx:33};
以上都是响应式的。
或者直接把msg替换了也是响应式的,因为msg也有对应的getter和setter(文档中这一句:this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) 也只是变相地使用了这个规则而已)
注意:数组对象是个例外,vue会为数组对象本身设置getter和setter,但不会为数组对象内的属性0,1,以及length属性设置getter和setter,假如元素为对象,则会为这个对象内的属性设置getter和setter:
对于规则:Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。
以上面的代码为例,不允许动态创建与msg同级别的属性。但可以通过set往msg中动态添加属性:
Vue.set(app.msg,"c",998) Vue.set(app.msg,"d",{ x:458 })
通过set添加的属性,都会被设置setter和getter,如果值是对象,则对象中的属性也会被设置getter和setter:
数组的响应规则
以上可以发现,要想达到响应效果,不能纯粹以一个对象的角度来看待数组,需要一些vue内置的数组函数来帮忙
https://vuefe.cn/v2/guide/list.html#变化数组方法-Mutation-Methods