最早看vue官网文档的时候都有提到过,但是随着自己使用被把这种重要的点给忽略了,以至于偶尔会遇到这种问题,并且在解决过程中走了很多弯路。
首先看官网的文档
1.对于对象
Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
解决方法是使用this.$set(this.someObject,'b',2);给对象添加新属性;
这种情况我再项目上经常遇到的是对象的某个属性如isShow绑定到v-if之类的条件判断中,因为如果对象上没有值,v-if条件判断是转换为false的,这样容易忽略定义,还有ajax请求返回的数据中没有这个属性,但条件判断需要,经常是用到之后再添加,这样就容易出现问题。
对于根节点,即需要定义在data上的属性,如要后续要用到,最好提前在data上定义好默认值或空值,不要用到之后再用this.someName = 'xx'这样的;
2.对象数组
Vue 不能检测以下数组的变动:
1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
2.当你修改数组的长度时,例如:vm.items.length = newLength
对于改变数组的值也可以用this.$set(this.someArr, 1, 'newVal');另外改变数组本身的一些操作数组的方法都可以被监听到push(结尾添加)、unshift(开头添加)、pop(结尾删除)、shift(开头删除)、splice(指定位置删除添加)、sort(排序)、reverse(倒叙)。因为这些方法在vue源码中都被重新改写,调用这些方法都会被监测到,从而引发更新
自己之前一直对此比较模糊的原因:
因为有时候明明错误的操作了,却会引起更新,有时可以,有时却不可以;最终多次实验发现,如果在一个同步队列中又其他可以争取引起更新的操作,其他不正确的操作也可以被监听到;
比如:this.name = 'newName' //name在data已经定义; this.arr1[0] = 'xxx';这种也会引起更新。