当前位置:首页 > VUE

vue依赖收集的实现

2026-01-22 03:51:53VUE

Vue 依赖收集的实现原理

Vue 的依赖收集是通过响应式系统实现的,核心在于 ObserverDepWatcher 三者的协作。

响应式数据初始化

通过 Object.definePropertyProxy(Vue 3)劫持数据对象的属性访问。在 getter 中触发依赖收集,在 setter 中触发更新通知。

vue依赖收集的实现

function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) {
        dep.depend(); // 收集依赖
      }
      return val;
    },
    set(newVal) {
      if (val === newVal) return;
      val = newVal;
      dep.notify(); // 触发更新
    }
  });
}

Dep 类管理依赖

Dep 是依赖管理器,每个响应式属性对应一个 Dep 实例,用于存储所有依赖该属性的 Watcher

vue依赖收集的实现

class Dep {
  constructor() {
    this.subs = []; // 存储 Watcher 实例
  }
  depend() {
    if (Dep.target) {
      this.subs.push(Dep.target); // 添加 Watcher
    }
  }
  notify() {
    this.subs.forEach(watcher => watcher.update()); // 通知更新
  }
}
Dep.target = null; // 全局唯一 Watcher 标记

Watcher 类触发依赖

Watcher 是观察者,在组件渲染或计算属性求值时被创建。它会将自身赋值给 Dep.target,触发属性的 getter 从而完成依赖收集。

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); // 触发 getter
    Dep.target = null; // 收集完成后清除标记
    return value;
  }
  update() {
    this.run();
  }
  run() {
    const value = this.get();
    if (value !== this.value) {
      this.cb.call(this.vm, value, this.value);
    }
  }
}

依赖收集流程

  1. 组件初始化时创建 Watcher,触发 get 方法。
  2. Dep.target 被设置为当前 Watcher
  3. 访问响应式数据时触发 getter,调用 dep.depend()Watcher 存入 subs
  4. 数据变化时触发 setter,调用 dep.notify() 通知所有 Watcher 更新。

Vue 3 的优化

Vue 3 改用 Proxy 实现响应式,依赖收集逻辑类似但更高效:

  • 通过 track 函数收集依赖(对应 depend)。
  • 通过 trigger 函数触发更新(对应 notify)。
  • 使用 WeakMapSet 存储依赖关系,避免内存泄漏。

标签: vue
分享给朋友:

相关文章

vue实现文档分享

vue实现文档分享

Vue 实现文档分享功能 文档分享功能通常涉及文件上传、存储、生成分享链接以及权限控制等模块。以下是基于 Vue 的实现方案: 文件上传组件 使用 element-ui 或 ant-design-…

vue实现好评弹框

vue实现好评弹框

Vue 实现好评弹框的方法 使用 Vue 实现好评弹框可以通过组件化方式完成,结合动态数据绑定和事件处理。以下是具体实现步骤: 1. 创建弹框组件 新建一个 RatingDialog.vue 组件…

vue实现下载暂停

vue实现下载暂停

Vue实现下载暂停功能 在Vue中实现下载暂停功能,通常需要结合XMLHttpRequest或Fetch API的AbortController来控制请求中断。以下是具体实现方法: 使用XMLH…

vue穿梭框组件实现

vue穿梭框组件实现

实现基础穿梭框组件 在Vue中实现穿梭框组件,可以使用<el-transfer>(Element UI)或手动实现。以下是手动实现的核心逻辑: <template> &l…

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { lette…

vue实现用户信息删除

vue实现用户信息删除

Vue 实现用户信息删除功能 在 Vue 中实现用户信息删除功能通常涉及前端界面交互和后端 API 调用。以下是实现步骤: 前端界面设计 创建删除按钮或操作项,通常使用 @click 事件触发删除…