当前位置:首页 > VUE

vue 实现响应式底层

2026-01-22 17:27:41VUE

Vue 响应式原理核心机制

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

数据劫持实现方式

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

vue 实现响应式底层

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。

vue 实现响应式底层

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 等变异方法,在保持原生功能的同时触发更新。

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.js 实现一个博客系统可以分为前端和后端两部分。以下是基于 Vue 的前端实现方案,后端可以选择 Node.js、Django 或其他框架。 项目初始化 使…

vue 实现排序

vue 实现排序

Vue 实现排序的方法 使用计算属性实现排序 通过计算属性对数组进行排序,可以保持原始数据不变。示例代码展示了如何对列表按名称升序排序: <template> <div>…

自己实现vue

自己实现vue

实现简易版 Vue.js 核心功能 要实现一个简易版 Vue.js,需要理解其核心功能:数据响应式、模板编译、依赖收集和虚拟 DOM。以下分模块实现关键功能。 数据响应式(Reactivity) 通…

vue实现数据删除

vue实现数据删除

vue实现数据删除的方法 使用v-for和v-on指令 在Vue中可以通过v-for指令渲染列表数据,结合v-on指令监听删除事件。定义一个方法处理删除逻辑,通常使用splice方法从数组中移除指定项…

vue实现弹层

vue实现弹层

Vue 实现弹层的方法 使用 Vue 原生组件实现弹层 创建一个基础的弹层组件,利用 v-if 或 v-show 控制显示隐藏。 <template> <div class="…

vue实现路线导航

vue实现路线导航

Vue 实现路由导航的方法 在 Vue 中实现路由导航通常使用 Vue Router 库,它是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。以下是几种常见的实现方式: 安装 Vue…