当前位置:首页 > VUE

vue 实现响应式底层

2026-01-22 17:27:41VUE

Vue 响应式原理核心机制

Vue 的响应式系统基于 JavaScript 的 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现,通过数据劫持结合发布-订阅模式完成依赖收集与更新触发。

数据劫持实现方式

Vue 2 使用 Object.defineProperty 通过递归遍历数据对象,对每个属性设置 getter/setter 拦截操作。当数据被访问时收集依赖,数据变化时通知更新。

function defineReactive(obj, key) {
  let value = obj[key]
  const dep = new Dep() // 依赖收集器

  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) {
        dep.depend() // 收集当前依赖
      }
      return value
    },
    set(newVal) {
      if (newVal === value) return
      value = newVal
      dep.notify() // 触发更新
    }
  })
}

Vue 3 使用 Proxy 直接代理整个对象,无需递归初始化属性,可拦截动态新增属性等操作。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key) // 追踪依赖
      return Reflect.get(target, key)
    },
    set(target, key, value) {
      Reflect.set(target, key, value)
      trigger(target, key) // 触发更新
      return true
    }
  })
}

依赖收集与派发更新

Dep 类实现 每个响应式属性对应一个 Dep 实例,用于存储所有依赖该属性的 Watcher。

class Dep {
  constructor() {
    this.subscribers = new Set()
  }

  depend() {
    if (Dep.target) {
      this.subscribers.add(Dep.target)
    }
  }

  notify() {
    this.subscribers.forEach(watcher => watcher.update())
  }
}

Watcher 机制 作为观察者,在组件渲染时创建,将自身设置为 Dep.target 以便收集依赖。

class Watcher {
  constructor(vm, expOrFn) {
    this.vm = vm
    this.getter = parsePath(expOrFn)
    this.value = this.get()
  }

  get() {
    Dep.target = this
    const value = this.getter.call(this.vm, this.vm)
    Dep.target = null
    return value
  }

  update() {
    this.run()
  }
}

数组响应式处理

Vue 对数组方法进行特殊处理,重写 pushpop 等变异方法,在保持原生功能的同时触发更新。

vue 实现响应式底层

const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto)

['push', 'pop', 'shift'].forEach(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
  })
})

性能优化策略

  • 异步更新队列:通过 nextTick 将多次数据变更合并为单次渲染
  • 虚拟 DOM 比对:减少直接 DOM 操作带来的性能损耗
  • 组件级更新:精确追踪每个组件的依赖关系,避免不必要的子组件更新

响应式系统工作流程

  1. 初始化阶段:递归转换数据为响应式对象,建立属性与 Dep 的关联
  2. 依赖收集阶段:组件渲染触发 getter,将当前 Watcher 注册到对应 Dep
  3. 更新触发阶段:数据变更触发 setter,Dep 通知所有关联 Watcher 更新
  4. 批量更新阶段:通过队列机制异步执行实际 DOM 更新操作

标签: 底层vue
分享给朋友:

相关文章

vue里实现增删改查

vue里实现增删改查

在Vue中实现增删改查 数据初始化 在Vue组件的data中定义初始数据和表单绑定的变量: data() { return { items: [ { id: 1, name:…

vue菜单实现

vue菜单实现

Vue 菜单实现方法 使用 Element UI 的菜单组件 Element UI 提供了现成的菜单组件,适合快速实现导航菜单。安装 Element UI 后,可以直接使用 el-menu 相关组件。…

vue实现xss

vue实现xss

XSS 攻击简介 XSS(跨站脚本攻击)是一种常见的安全漏洞,攻击者通过注入恶意脚本到网页中,当其他用户访问该页面时,脚本会在其浏览器中执行,可能导致数据泄露或会话劫持。 Vue 中的 XSS…

vue实现active

vue实现active

Vue 实现 active 状态的方法 在 Vue 中实现 active 状态可以通过以下几种方式实现,具体取决于使用场景和需求。 使用 v-bind:class 动态绑定类名 通过 v-bind:…

vue实现编辑

vue实现编辑

Vue 实现编辑功能 在 Vue 中实现编辑功能通常涉及表单绑定、状态管理和事件处理。以下是一个常见的实现方法: 双向数据绑定 使用 v-model 指令实现表单元素与数据的双向绑定: <i…

vue nexttick实现

vue nexttick实现

Vue 中 nextTick 的实现原理 Vue 的 nextTick 是一个用于在下次 DOM 更新循环结束之后执行延迟回调的方法。它的核心实现依赖于 JavaScript 的事件循环机制。 基本…