当前位置:首页 > VUE

vue依赖收集实现

2026-01-17 22:29:07VUE

Vue 依赖收集实现原理

Vue 的依赖收集机制是其响应式系统的核心,主要通过 ObserverDepWatcher 三个类协作完成。

核心流程

Observer 数据劫持 通过 Object.definePropertyProxy 拦截对象属性的读写操作。在 getter 中收集依赖,在 setter 中触发更新。

vue依赖收集实现

class Observer {
  constructor(value) {
    this.walk(value)
  }
  walk(obj) {
    Object.keys(obj).forEach(key => {
      defineReactive(obj, key, obj[key])
    })
  }
}

Dep 依赖管理 每个被观察的属性会创建一个 Dep 实例,用于存储所有依赖该属性的 Watcher

class Dep {
  constructor() {
    this.subs = new Set()
  }
  addSub(watcher) {
    this.subs.add(watcher)
  }
  notify() {
    this.subs.forEach(watcher => watcher.update())
  }
}

Watcher 观察者 在计算属性、模板编译等场景创建,保存更新逻辑。触发 getter 时会被添加到对应 Dep 中。

vue依赖收集实现

class Watcher {
  constructor(vm, expOrFn, cb) {
    this.vm = vm
    this.getter = parsePath(expOrFn)
    this.cb = cb
    this.value = this.get()
  }
  get() {
    Dep.target = this // 标记当前watcher
    const value = this.getter.call(this.vm, this.vm)
    Dep.target = null
    return value
  }
  update() {
    this.run()
  }
  run() {
    const value = this.get()
    if (value !== this.value) {
      const oldValue = this.value
      this.value = value
      this.cb.call(this.vm, value, oldValue)
    }
  }
}

依赖收集过程

  1. 初始化阶段通过 Observer 递归地将数据对象转为响应式
  2. 模板编译时遇到插值表达式或指令会创建 Watcher
  3. Watcher 在求值过程中触发属性的 getter
  4. getter 中通过 Dep.target 判断当前是否有活跃的 Watcher
  5. 如果存在则将 Watcher 添加到属性的 Dep
  6. 数据变更时触发 setter,通过 Dep.notify() 通知所有关联 Watcher 更新

数组处理特殊逻辑

对于数组类型,Vue 通过拦截以下方法实现响应式:

  • push/pop/shift/unshift/splice/sort/reverse 通过重写这些方法,在变更数组时手动触发通知。
const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto)
;['push','pop','shift','unshift','splice','sort','reverse'].forEach(method => {
  const original = arrayProto[method]
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    ob.dep.notify()
    return result
  }
})

现代实现改进

Vue 3 改用 Proxy 实现依赖收集,优势包括:

  • 可检测新增/删除属性
  • 更好的数组变化检测
  • 性能优化避免递归遍历

Proxy 版本的依赖收集通过 tracktrigger 函数实现,原理类似但实现更简洁。

标签: vue
分享给朋友:

相关文章

vue 实现全选

vue 实现全选

Vue 实现全选功能 在 Vue 中实现全选功能通常需要结合复选框的状态管理,以下是几种常见的实现方式: 使用 v-model 绑定数组 通过 v-model 绑定一个数组来管理选中的项,全选时将…

vue实现组件循环

vue实现组件循环

Vue 组件循环的实现方法 在 Vue 中实现组件循环通常使用 v-for 指令,可以循环渲染数组或对象的数据到组件上。 基本数组循环 通过 v-for 指令遍历数组,渲染多个相同结构的组件。…

vue实现购物按钮

vue实现购物按钮

Vue 购物按钮实现方法 基础按钮实现 使用 Vue 的模板语法创建基础按钮组件,绑定点击事件处理购物逻辑: <template> <button @click="addToC…

前端多线程实现vue

前端多线程实现vue

前端多线程与Vue的结合 在Vue中实现多线程通常通过Web Worker技术完成。Web Worker允许在后台线程中运行脚本,避免阻塞主线程,适合处理计算密集型任务。 使用Web Worker…

vue查看更多怎么实现

vue查看更多怎么实现

实现 Vue 的“查看更多”功能 数据截取与显示控制 通过 v-if 或 v-show 控制内容的显示与隐藏。初始状态下只显示部分内容,点击“查看更多”后展开完整内容。 <template&…

vue实现点击页面切换

vue实现点击页面切换

实现点击页面切换功能 在Vue中实现点击页面切换功能,可以通过路由跳转或组件动态渲染两种方式完成。以下是具体实现方法: 使用Vue Router实现页面跳转 安装Vue Router后,在项目中配置…