Vue 2.0 在检测数组变化时,由于 JavaScript 的限制(Object.defineProperty
不能直接用于数组元素),它采用了特殊的策略来跟踪数组的变更。以下是 Vue 2.0 检测数组变化的主要方法:
-
数组方法重写:
Vue 重写了数组的一些方法,如push
、pop
、shift
、unshift
、splice
、sort
和reverse
。当这些方法被调用时,Vue 会检测到数组的变更,并触发视图更新。这是通过把 Vue 的实例的
_data
对象上的数组转换为原型链上的方法实现的。因此,当你调用如this.items.push(newItem)
时,实际上调用的是 Vue 重写后的方法,而不是原生的数组方法。 -
使用
$set
方法:
对于直接通过索引修改数组元素或修改数组长度的情况,Vue 无法检测到这些变更。因此,Vue 提供了一个全局方法Vue.set
(在组件实例中可以通过this.$set
访问)来确保这些变更能够被检测到。例如:
this.$set(this.items, index, newValue); // 修改数组元素 this.items.splice(index, 1, newValue); // 另一种修改数组元素的方式,Vue 可以检测到
-
注意事项:
- 当你使用
filter()
、concat()
或map()
等方法时,这些方法返回的是新数组,而不是修改原数组。因此,你需要将新数组赋值给原数组变量,才能触发视图更新。 - 使用
length
属性直接修改数组长度也不会触发视图更新。
- 当你使用
-
性能考虑:
由于 Vue 需要追踪数组的变化,并可能触发视图更新,所以直接修改数组元素(不使用 Vue 的重写方法)可能会导致性能问题,特别是在处理大型数组时。因此,最好总是使用 Vue 提供的数组方法来修改数组。 -
Vue 3.x 中的改进:
Vue 3.x 使用了 Proxy 来代替Object.defineProperty
,从而能够更高效地检测数组变化。Proxy 可以直接用于数组,而无需重写其方法。这使得 Vue 3.x 在处理数组时更加灵活和高效。