总结: 有三种情况下, 数据更新, 视图不更新
1, 通过数组的索引直接修改数组中这个索引对应的数据
2, data中定义的对象, 初始化之后,再通过打点定义属性, 新增的属性不能更新
3, data中没有定义的变量, 不能更新
<body>
<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
<div id='myApp'>
注: true表示可以更新 false表示不能更新
1,<input type="text" v-model="arr1[0]"> {{arr1}} <hr> true v-model底层通过set函数更新数据
1,<input type="text" :value="arr1[0]" @input="change1"> <hr> false change1中使用数组的索引更新数组的数据
2,<input type="text" v-model="arr2[0].name"> {{arr2}} <hr> true v-model底层通过set函数更新数据
2,<input type="text" :value="arr2[0].name" @input="change2"> <hr> true change2中更新的实质上是对象的属性, 而不是数组的索引值
3,<input type="text" v-model="obj3.age"> {{obj3}} <hr> true 对象属性修改,可以更新
4,<input type="text" v-model="obj4.age"> {{obj4}} <hr> true 对象属性值默认是undefined, 绑定时,vue内部会创建这个属性,自动实现其set函数
5,<input type="text" v-model="obj5.age"> {{obj5}} <hr> false 对象属性通过打点定义赋值,并没有定义set函数, 不能更新,
6,<input type="text" v-model="obj6.age"> {{obj6}} <hr> false obj6=obj5属于浅赋值, 内存地址不变, 和obj原理一样
7,<input type="text" v-model="obj7.age"> {{obj7}} <hr> false obj7没有在data中定义,不是动态数据, vue底层不会实现它的set函数
8,<input type="text" v-model="obj8.age"> {{obj8}} <hr> true obj8在data中有定义, 是动态数据, 重新赋值时,vue底层会重新实现set函数
9,<input type="text" v-model="obj9.age"> {{obj9}} <hr> true obj9是obj5的深复制结果, 相当于新对象, 原理和obj8相同
</div>
<script>
new Vue({
el: '#myApp',
data: {
arr1: [1],
arr2: [{name: "2"}],
obj3: {age: 10},
obj4: {},
obj5: {},
obj8: null,
obj9: null
},
methods: {
change1(e){
this.arr1[0] = e.target.value
},
change2(e){
this.arr2[0].name = e.target.value
}
},
created() {
// 一个对象创建之后,如果需要新增字段, 不要直接调用, 因为直接调用添加的属性没有实现set/get函数, 导致这个属性值更新时, 不会调用set函数 视图就不会刷新,
this.obj5.age = 20;
this.obj5["age"] = 20;
// 解决方案1: 通过Object.defineProperty 给对象定义新字段,并实现set函数,在set函数中实现虚拟DOM更新 (自己实现太复杂)
// 解决方案2: 给data中定义的字段赋值新的对象, 即可更新, 保证data中有定义, 否则不可更新
this.obj6 = this.obj5;
this.obj7 = { age : this.obj5.age}
this.obj8 = { age : 20}
// 解决方案3: 通过深复制,给data中的字段设置新值
this.obj9 = JSON.parse(JSON.stringify(this.obj5)) ;
}
})
</script>
</body>