当前位置:首页 > 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实现前端分离

vue实现前端分离

Vue 实现前后端分离 前后端分离是一种架构模式,前端负责页面渲染和交互逻辑,后端提供数据接口。Vue.js 作为前端框架,非常适合实现前后端分离的开发模式。 核心实现步骤 创建 Vue 项目 使…

vue实现路由导航

vue实现路由导航

路由导航的实现方式 在Vue中,路由导航主要通过Vue Router实现。Vue Router是Vue.js官方的路由管理器,用于构建单页面应用(SPA)。 基本路由配置 安装Vue Router…

vue实现皮肤切换

vue实现皮肤切换

实现皮肤切换的基本思路 在Vue中实现皮肤切换功能,通常涉及动态修改CSS变量或类名。核心是通过状态管理当前主题,并在组件中应用对应的样式。 使用CSS变量实现主题切换 CSS变量(自定义属性)是实…

vue实现选择季度

vue实现选择季度

Vue 实现选择季度的几种方法 使用下拉选择框(Select) 在 Vue 中可以通过 v-model 绑定一个下拉选择框来实现季度选择。数据可以预先定义为一个包含季度选项的数组。 <…

vue怎么实现动画

vue怎么实现动画

Vue 动画实现方法 Vue 提供了多种方式实现动画效果,包括内置过渡系统、第三方库集成以及 CSS 动画。以下是常见实现方法: 使用 Vue 过渡系统 通过 <transition>…

vue实现好友列表

vue实现好友列表

实现好友列表的Vue组件 数据准备 在Vue组件的data中定义好友列表数据,通常是一个数组对象,每个对象包含好友的基本信息如ID、头像、昵称等。 data() { return { f…