当前位置:首页 > VUE

vue 数组响应式实现

2026-02-22 19:50:07VUE

Vue 数组响应式实现原理

Vue 通过重写数组的原型方法实现对数组变化的监听。核心思路是拦截数组的变异方法(如 pushpopsplice 等),在方法执行前后触发依赖更新。

重写数组原型

Vue 创建了一个继承自 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 会遍历对象属性,对数组进行特殊处理:

vue 数组响应式实现

class Observer {
  constructor(value) {
    if (Array.isArray(value)) {
      value.__proto__ = arrayMethods
      this.observeArray(value)
    } else {
      this.walk(value)
    }
  }

  observeArray(items) {
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])
    }
  }
}

处理新增元素

对于可能新增元素的方法(pushunshiftsplice),需要对新元素进行响应式处理:

if (inserted) ob.observeArray(inserted)

触发更新

每个被观察的数组都有一个关联的 Dep 实例,当数组变化时通过 dep.notify() 通知所有订阅者:

vue 数组响应式实现

ob.dep.notify()

注意事项

直接通过索引修改数组元素或修改数组长度不会被检测到:

vm.items[index] = newValue // 非响应式
vm.items.length = newLength // 非响应式

应使用 Vue.set 或数组的变异方法:

Vue.set(vm.items, index, newValue)
vm.items.splice(index, 1, newValue)

总结

Vue 的数组响应式实现通过以下方式工作:

  • 创建继承自原生数组原型的变异版本
  • 重写会修改数组的7个方法
  • 方法执行后对新元素进行响应式处理
  • 通过依赖收集和通知机制触发视图更新
  • 提供 Vue.set 和变异方法作为修改数组的安全方式

标签: 数组vue
分享给朋友:

相关文章

vue实现检测数组

vue实现检测数组

Vue 中检测数组变化的方法 Vue 的响应式系统无法直接检测到数组的某些变化,因为 JavaScript 的限制。以下是一些解决方案: 使用 Vue.set 或 this.$set Vue 提供…

vue 实现拖动

vue 实现拖动

Vue 实现拖动的几种方法 在Vue中实现拖动功能可以通过多种方式,包括原生HTML5的拖放API、第三方库如vuedraggable等。以下是几种常见的实现方法: 使用HTML5拖放API HTM…

vue实现getapp

vue实现getapp

Vue 中实现全局获取应用实例的方法 在 Vue 3 中,可以通过 getCurrentInstance 方法获取当前组件实例,但需要明确其使用场景和限制。以下是具体实现方式: 方法一:通过 get…

vue 实现登录

vue 实现登录

Vue 实现登录功能 创建登录表单组件 在 Vue 项目中创建一个登录表单组件(如 Login.vue),包含用户名和密码输入框以及提交按钮。使用 v-model 实现双向数据绑定。 <tem…

vue ref实现

vue ref实现

Vue 中 ref 的实现 在 Vue 中,ref 是一个用于创建响应式引用的 API,适用于基本类型和对象。以下是 ref 的核心实现原理和使用方法。 基本实现原理 ref 通过 Reactive…

vue实现京东

vue实现京东

Vue 实现京东电商网站的关键步骤 项目搭建与基础配置 使用 Vue CLI 或 Vite 初始化项目,安装 Vue Router 管理路由,Vuex/Pinia 管理状态。配置基础 UI 框架如 E…