vue数组实现原理
Vue 数组响应式原理
Vue 通过重写数组的原型方法来实现对数组变化的监听。具体实现基于 JavaScript 的原型继承和对象劫持技术。
核心实现机制
Vue 创建了一个继承自原生 Array 原型的对象,并重写了会改变数组内容的 7 个方法:

- push
- pop
- shift
- unshift
- splice
- sort
- reverse
这些方法被调用时会先执行原生数组方法,然后通知依赖更新。以下是简化后的实现代码示例:
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 会递归地将它们转换为响应式对象。对于基本类型元素则不会进行监听,因为 JavaScript 的限制无法直接监听基本类型值的变化。

function observeArray(items) {
for(let i = 0, l = items.length; i < l; i++) {
observe(items[i])
}
}
无法检测的情况
直接通过索引修改数组元素或修改数组长度不会被检测到:
vm.items[index] = newValue // 不会触发更新
vm.items.length = newLength // 不会触发更新
解决方案
使用 Vue.set 或数组的 splice 方法来触发响应式更新:
Vue.set(vm.items, index, newValue)
// 或
vm.items.splice(index, 1, newValue)
性能优化考虑
Vue 选择只重写会改变数组内容的方法,而不是深度监听每个数组元素的变化,这种设计在性能和功能之间取得了平衡。对于大型数组,这种实现方式能显著减少性能开销。






