vue数组实现原理
Vue 数组响应式原理
Vue 通过重写数组的变异方法(如 push、pop、splice 等)来实现数组的响应式。当这些方法被调用时,Vue 能够检测到变化并触发视图更新。
重写的数组方法
Vue 重写了以下数组方法:
pushpopshiftunshiftsplicesortreverse
这些方法被调用时,Vue 会执行以下操作:

- 调用原始的数组方法完成数据变更。
- 通知依赖(Watcher)进行更新。
实现细节
Vue 通过 Object.create(Array.prototype) 创建一个新的原型对象,并将重写的方法挂载到这个原型上。然后将数组实例的原型指向这个新创建的对象。
示例代码:

const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto)
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
methodsToPatch.forEach(function (method) {
const original = arrayProto[method]
def(arrayMethods, method, function mutator (...args) {
const result = original.apply(this, args)
const ob = this.__ob__
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if (inserted) ob.observeArray(inserted)
ob.dep.notify()
return result
})
})
无法检测的情况
Vue 无法检测以下数组变动:
- 通过索引直接设置项:
vm.items[index] = newValue - 修改数组长度:
vm.items.length = newLength
解决方法:
// 使用 Vue.set 或 this.$set
Vue.set(vm.items, index, newValue)
// 使用 splice
vm.items.splice(index, 1, newValue)
对象数组的响应式
对于对象数组,Vue 会对数组中的每个对象进行响应式处理。当对象属性发生变化时,也能触发视图更新。
性能考虑
Vue 没有对数组的每个索引都进行响应式处理,而是通过重写变异方法来实现。这种设计在性能和功能之间取得了平衡。






