当前位置:首页 > 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中实现分类功能通常涉及数据分组、动态渲染和交互逻辑。以下是几种常见的实现方式: 基于计算属性的分类 通过计算属性对原始数据进行分组处理,适合静态或少量数据分类: com…

vue实现数组

vue实现数组

Vue 实现数组操作的方法 在 Vue 中,数组的操作需要特别注意响应式的问题。Vue 提供了一些方法来确保数组的变动能够触发视图更新。 响应式数组方法 Vue 对以下数组方法进行了封装,确保它们能…

自实现vue

自实现vue

实现 Vue 的核心功能 要实现一个简化版的 Vue,需要理解其核心功能:数据响应式、模板编译、虚拟 DOM 和组件系统。以下是关键步骤的分解: 数据响应式 Vue 使用 Object.define…

vue实现画板

vue实现画板

Vue 实现画板功能 在 Vue 中实现画板功能可以通过 HTML5 的 Canvas API 实现。以下是一个完整的实现方案: 创建 Vue 组件 新建一个 Vue 单文件组件(SFC),命名为…

vue实现爬虫

vue实现爬虫

Vue 实现爬虫的基本思路 Vue.js 本身是一个前端框架,主要用于构建用户界面。要实现爬虫功能,通常需要结合后端技术或浏览器自动化工具。以下是几种常见的方法: 方法一:Vue + Node.js…

vue for实现

vue for实现

Vue 中的 v-for 指令 v-for 是 Vue.js 中用于渲染列表数据的核心指令,通过遍历数组或对象生成动态内容。 基本语法(数组) <ul> <li v-for="…