当前位置:首页 > 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 中实现静态查询通常指不依赖后端接口,直接在前端处理数据筛选或搜索功能。以下是几种常见实现方式: 使用计算属性过滤数据 通过计算属性对静态数据进行筛选,适合简单查询…

vue实现多级组件

vue实现多级组件

实现多级组件的基本结构 在Vue中实现多级组件通常涉及父子组件嵌套,通过props向下传递数据,通过$emit向上传递事件。多级组件的核心是递归或动态组件渲染。 <!-- 父组件 Parent…

vue实现皮肤切换

vue实现皮肤切换

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

vue实现放大效果

vue实现放大效果

使用 CSS transform 实现放大效果 在 Vue 中实现放大效果可以通过 CSS 的 transform: scale() 属性。这种方法简单高效,适合大多数交互场景。 定义一个 CSS…

vue为啥能实现监听

vue为啥能实现监听

Vue 实现监听的原理 Vue 的监听能力主要基于其响应式系统,该系统通过数据劫持和依赖收集实现。当数据变化时,系统能自动触发视图更新或执行回调函数。 核心机制:Object.definePrope…

vue实现文字播放栏

vue实现文字播放栏

Vue 实现文字播放栏(跑马灯效果) 方法一:使用 CSS 动画 + Vue 数据绑定 通过 CSS 的 @keyframes 实现动画效果,结合 Vue 的动态数据绑定控制内容。 <tem…