当前位置:首页 > VUE

vue依赖收集实现

2026-01-17 22:29:07VUE

Vue 依赖收集实现原理

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

核心流程

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

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 中。

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 实现年历的方法 使用 Vue 实现年历可以通过组件化开发方式,结合日期计算和动态渲染完成。以下是两种常见的实现方式: 基于原生 Vue 的日历组件 创建 Calendar.vue 组件文件…

vue实现前端注册

vue实现前端注册

Vue 实现前端注册功能 注册表单设计 使用 Vue 的模板语法创建注册表单,包含用户名、邮箱、密码和确认密码字段。表单需绑定 v-model 实现双向数据绑定。 <template>…

vue实现多层评论回复

vue实现多层评论回复

Vue 实现多层评论回复 数据结构设计 多层评论通常采用嵌套结构,每个评论对象包含子评论数组。示例数据结构如下: comments: [ { id: 1, content: '父…

vue路由实现内部切换

vue路由实现内部切换

Vue 路由实现内部切换的方法 Vue Router 是 Vue.js 官方的路由管理器,用于实现单页应用(SPA)的页面切换。以下是几种常见的内部路由切换方式: 使用 <router-lin…

vue实现走势图

vue实现走势图

Vue 实现走势图的方法 使用 ECharts 库 ECharts 是一个强大的数据可视化库,支持多种图表类型,包括走势图(折线图)。在 Vue 项目中可以通过 vue-echarts 封装库或直接使…

vue实现导航栏切图

vue实现导航栏切图

Vue 实现导航栏切图 使用 Vue Router 实现基础导航 在 Vue 项目中,可以通过 Vue Router 实现导航栏的路由切换。创建一个导航栏组件,并在其中使用 <router-li…