vue数组实现原理
Vue 数组响应式原理
Vue 通过重写数组的变异方法(如 push、pop、shift、unshift、splice、sort、reverse)来实现对数组变化的监听。这些方法被修改后,会在执行原有逻辑的同时触发视图更新。
核心实现机制
Vue 使用 Object.defineProperty 对数组的变异方法进行拦截。具体步骤如下:
-
创建拦截器对象
定义一个对象,包含与原生数组方法同名的方法,但在执行时会额外触发依赖通知。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__ ob.dep.notify() return result }) }) -
覆盖目标数组的原型
当 Vue 初始化数据时,如果遇到数组,会将数组的原型指向自定义的拦截器对象。if (Array.isArray(value)) { const augment = hasProto ? protoAugment : copyAugment augment(value, arrayMethods, arrayKeys) this.observeArray(value) } -
处理新增元素
对于push、unshift、splice等方法新增的元素,Vue 会遍历这些新元素并将其转换为响应式数据。if (inserted) ob.observeArray(inserted)
无法检测的情况
由于 JavaScript 的限制,Vue 无法检测以下数组变动:
- 直接通过索引设置项(如
arr[0] = newValue) - 修改数组长度(如
arr.length = 0)
解决方法:
- 使用
Vue.set或vm.$setVue.set(arr, index, newValue) - 使用
splicearr.splice(index, 1, newValue)
源码关键点
在 Vue 2.x 源码中,数组响应式处理主要在 src/core/observer/index.js 和 src/core/observer/array.js 文件中实现。核心是通过拦截数组方法并触发依赖更新,同时对新元素进行响应式处理。







