总结: 有三种情况下, 数据更新, 视图不更新
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>
