在vue2的项目中,有时会遇到修改数组的参数时,不会触发响应式变化,还需要单独来触发,实现响应式监听,这次就来探究一下为什么数组在v2中有时不会触发响应式。
不会触发响应式情况
在官方文档中已经说明不会触发响应式更新的案例。
有两种情况不会触发数组的响应式更新:
通过下标索引来直接设置和修改数组
修改数组的长度length树形
js
data() {
return {
testArr:['1' , '2'],
}
},
不会触发响应式变化情况
this.testArr[1] = '3' // 不会触发响应式变化
this.testArr.length = 1 // 不会触发响应式变化
解决办法
使用$set的方法手动添加监听
可以使用数组本身的方法也可以实现监听(push,unshift,pop,splice...)
js
this.$set(this.testArr, 1, "我被修改了"); // 可以在方法中手动添加改变,触发监听
this.testArr.splice(1, 1, "我被修改了")
原因
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。
我们知道vue2的双向绑定使用的是object.defineProperty(),经过测试,object.defineProperty()是可以监听到数组下标的变化
js
let arr = [1,2,3,4]
Object.defineProperty(arr,1,{
get:function() {
console.log('调用了');
},
set:function(newVal) {
console.log('修改了',newVal);
},
})
arr[1] = 5; // 根据下标修改时,触发了set函数,可以被监听到
- 所以object.defineProperty()是可以监听到数组的下标变化,vue2因为性能问题放弃了这个属性
在vue3中,使用的proxy实现的双向绑定,所以当使用vue3对数组的下标进行修改时,还会触发响应式