Vue追踪数组变化使视图自动更新的方式
- 重写数组方法
- Vue在初始化过程中,对数组的7个变异方法(
push
、pop
、shift
、unshift
、splice
、sort
、reverse
)进行了重写。
- 例如,当调用
arr.push(1)
时,实际调用的是Vue重写后的push
方法。在这个重写方法内部,首先会调用原生的push
方法执行正常的数组操作,然后通知依赖收集器,数组发生了变化,从而触发视图更新。
- 依赖收集
- 在Vue的响应式系统中,每个组件实例都有一个
Watcher
实例,它会在组件渲染过程中收集依赖。当模板中使用到数组时,Watcher
会收集数组相关的依赖。
- 当数组通过变异方法改变时,重写的方法会通知这些依赖,进而触发视图更新。
Vue.set()方法在处理数组响应式时的原理
- 原理
Vue.set()
方法主要用于向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。对于数组,Vue.set()
方法会调用Array.prototype.splice
方法。
- 例如,
Vue.set(arr, index, newVal)
实际上会执行arr.splice(index, 1, newVal)
。通过这种方式,触发了数组的变异,从而让Vue的响应式系统能够检测到数组的变化。
- 应用场景
- 直接通过索引修改数组元素:当直接使用索引修改数组元素时,如
arr[index] = newVal
,Vue无法检测到变化。此时就需要使用Vue.set(arr, index, newVal)
,例如:
<template>
<div>
<ul>
<li v - for="(item, index) in arr" :key="index">{{item}}</li>
</ul>
<button @click="updateArray">更新数组</button>
</div>
</template>
<script>
export default {
data() {
return {
arr: [1, 2, 3]
};
},
methods: {
updateArray() {
// 错误方式,无法触发视图更新
// this.arr[0] = 4;
// 正确方式,使用Vue.set
this.$set(this.arr, 0, 4);
}
}
};
</script>
- 向数组中添加新元素:如果希望添加的新元素也能被Vue的响应式系统追踪,也可以使用
Vue.set()
。例如Vue.set(arr, arr.length, newItem)
,等同于arr.push(newItem)
,但这种方式在某些复杂逻辑下可以更灵活地控制添加操作并确保响应式。