当前位置:首页 > VUE

vue computed 实现原理

2026-01-16 19:19:36VUE

Vue Computed 实现原理

Vue 的 computed 属性是基于响应式依赖的缓存机制,其核心实现依赖于 Vue 的响应式系统和依赖收集机制。

依赖收集与缓存机制

computed 属性在初始化时会创建一个 Watcher 实例,并将 computedgetter 函数作为回调传入。当首次访问 computed 属性时,getter 函数会被执行,并在执行过程中触发依赖属性的 get 拦截器,从而将当前 Watcher 订阅到这些依赖属性的订阅列表中。

// 伪代码示例
function initComputed(vm, computed) {
  const watchers = {};
  for (const key in computed) {
    const getter = computed[key];
    watchers[key] = new Watcher(vm, getter, { lazy: true });
    defineComputed(vm, key, watchers[key]);
  }
}

惰性求值与缓存

computed 属性默认是惰性求值的,只有在被访问时才会计算值。如果依赖的响应式数据未发生变化,computed 会直接返回缓存的值,避免重复计算。

// Watcher 类中的相关逻辑
class Watcher {
  constructor(vm, expOrFn, options) {
    this.lazy = !!options.lazy;
    this.dirty = this.lazy; // 初始时为 true,表示需要重新计算
    this.getter = expOrFn;
    this.value = this.lazy ? undefined : this.get();
  }

  evaluate() {
    this.value = this.get();
    this.dirty = false;
  }

  get() {
    pushTarget(this); // 将当前 Watcher 设置为 Dep.target
    const value = this.getter.call(this.vm);
    popTarget(); // 恢复之前的 Watcher
    return value;
  }
}

依赖更新触发重新计算

computed 依赖的响应式数据发生变化时,依赖属性的 set 拦截器会通知所有订阅的 Watcher 执行更新。computedWatcher 会将 dirty 标记为 true,表示需要重新计算,但不会立即执行计算,而是等到下次访问时再重新求值。

// Watcher 更新逻辑
update() {
  if (this.lazy) {
    this.dirty = true; // 标记为脏数据,下次访问时重新计算
  } else {
    queueWatcher(this); // 非 lazy 的 Watcher 直接加入队列更新
  }
}

与模板的绑定

在模板中使用 computed 属性时,Vue 会在渲染过程中访问该属性,触发 getter 并收集依赖。如果依赖变化,会通知渲染 Watcher 重新渲染组件,从而间接触发 computed 的重新计算。

// 定义 computed 属性的 getter
function createComputedGetter(key) {
  return function computedGetter() {
    const watcher = this._computedWatchers[key];
    if (watcher.dirty) {
      watcher.evaluate(); // 重新计算
    }
    if (Dep.target) {
      watcher.depend(); // 收集上层 Watcher 的依赖
    }
    return watcher.value;
  };
}

总结

  • computed 通过 Watcher 实现惰性求值和缓存。
  • 依赖收集发生在首次访问时,后续访问直接返回缓存值(除非依赖变化)。
  • 依赖变化时标记为 dirty,下次访问时重新计算。
  • 与模板绑定时,会自动触发依赖收集和更新。

vue computed 实现原理

标签: 原理vue
分享给朋友:

相关文章

vue实现好友列表

vue实现好友列表

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

vue弹幕实现不重叠

vue弹幕实现不重叠

实现 Vue 弹幕不重叠的方法 CSS 定位与动画控制 通过绝对定位和动态计算弹幕轨道高度,确保弹幕在不同轨道上运行。每条弹幕占据固定高度的轨道,避免重叠。 // 弹幕轨道高度计算 const tr…

vue实现点击

vue实现点击

实现点击事件的基本方法 在Vue中实现点击事件可以通过v-on指令或@简写方式绑定。以下是常见的点击事件绑定方法: <template> <button v-on:click…

vue实现框架

vue实现框架

Vue 框架实现的核心方法 基础项目搭建 使用 Vue CLI 或 Vite 快速初始化项目。Vue CLI 适合传统项目,Vite 更适合现代轻量级应用。安装后通过命令行工具选择所需配置(如 Rou…

vue slot实现

vue slot实现

vue slot 的实现方法 在 Vue 中,slot 是一种内容分发机制,允许父组件向子组件传递模板内容。以下是几种常见的 slot 实现方式: 默认 slot 默认 slot 是最基础的 slo…

vue实现granfana

vue实现granfana

Vue 实现类似 Grafana 的仪表盘 要在 Vue 中实现类似 Grafana 的仪表盘功能,需要结合数据可视化库、状态管理和 UI 组件。以下是关键步骤和推荐工具: 数据可视化库 使用…