当前位置:首页 > VUE

vue实现依赖收集

2026-01-08 15:22:41VUE

依赖收集的基本原理

Vue 的依赖收集基于观察者模式,通过 Object.definePropertyProxy 拦截数据的访问和修改。当数据被访问时,收集当前正在执行的依赖(如计算属性、模板渲染函数);当数据修改时,通知这些依赖进行更新。

核心实现步骤

定义 Dep 类 每个响应式数据属性对应一个 Dep 实例,用于管理依赖(即 Watcher 实例):

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeWatcher) {
      this.subscribers.add(activeWatcher);
    }
  }
  notify() {
    this.subscribers.forEach(watcher => watcher.update());
  }
}

定义 Watcher 类 Watcher 表示一个依赖,通常是组件渲染函数或计算属性:

vue实现依赖收集

let activeWatcher = null;

class Watcher {
  constructor(updateFn) {
    this.updateFn = updateFn;
    this.update();
  }
  update() {
    activeWatcher = this;
    this.updateFn();
    activeWatcher = null;
  }
}

实现响应式数据 通过 defineReactive 函数将普通对象转换为响应式对象:

function defineReactive(obj, key) {
  const dep = new Dep();
  let value = obj[key];

  Object.defineProperty(obj, key, {
    get() {
      dep.depend(); // 收集当前活跃的 Watcher
      return value;
    },
    set(newVal) {
      if (newVal !== value) {
        value = newVal;
        dep.notify(); // 通知所有依赖更新
      }
    }
  });
}

使用示例

创建响应式对象

vue实现依赖收集

const data = { count: 0 };
defineReactive(data, 'count');

创建依赖data.count 被访问时,自动收集依赖:

new Watcher(() => {
  console.log(`Count updated: ${data.count}`);
});

触发更新 修改 data.count 将自动触发 Watcher 的更新函数:

data.count++; // 输出 "Count updated: 1"

基于 Proxy 的实现(Vue 3)

Vue 3 使用 Proxy 替代 Object.defineProperty,核心逻辑类似但能拦截更多操作:

function reactive(obj) {
  const depsMap = new Map();

  return new Proxy(obj, {
    get(target, key) {
      let dep = depsMap.get(key);
      if (!dep) {
        dep = new Dep();
        depsMap.set(key, dep);
      }
      dep.depend();
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      const dep = depsMap.get(key);
      if (dep) dep.notify();
      return true;
    }
  });
}

关键点说明

  • 动态依赖收集:只有在数据被访问时才会收集当前活跃的 Watcher
  • 批量更新:Vue 实际实现中会使用异步队列(如 nextTick)优化多次数据变更的更新。
  • 嵌套依赖:组件或计算属性可能形成嵌套的依赖关系,Vue 通过依赖树管理这种场景。

标签: vue
分享给朋友:

相关文章

vue 实现toast

vue 实现toast

vue 实现 toast 的方法 在 Vue 中实现 Toast 提示功能可以通过多种方式,以下是几种常见的实现方法: 使用第三方库 Vue 生态中有许多成熟的 Toast 库,例如 vue-toa…

vue 实现直播

vue 实现直播

Vue 实现直播的基本方法 在Vue中实现直播功能,通常需要结合WebRTC、RTMP或HLS等技术。以下是几种常见的实现方式: 使用WebRTC实现实时直播 WebRTC适合低延迟的实时直播场景,…

vue实现高亮

vue实现高亮

Vue 实现文本高亮的方法 在 Vue 中实现文本高亮可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 v-html 指令 通过 v-html 指令可以动态插入 HTML 内容,将需要高…

vue vnode实现

vue vnode实现

Vue VNode 实现原理 VNode(Virtual Node)是 Vue 的核心概念之一,用于描述真实 DOM 的轻量级虚拟表示。VNode 的实现涉及以下关键点: VNode 的基本结构 V…

vue实现试卷

vue实现试卷

Vue实现试卷系统的基本思路 使用Vue.js构建试卷系统需要结合组件化开发、状态管理和后端数据交互。核心功能包括题目展示、答题逻辑、计时器和提交答案。 核心功能模块划分 试卷组件结构 试卷容器组…

vue实现导出

vue实现导出

Vue 实现导出功能的方法 在 Vue 项目中实现导出功能通常涉及将数据导出为 Excel、CSV 或其他格式。以下是几种常见的实现方式: 使用 xlsx 库导出 Excel 安装 xlsx 库:…