当前位置:首页 > VUE

vue computed实现原理

2026-02-18 18:03:27VUE

Vue computed 实现原理

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

依赖收集与缓存

computed 属性通过 Object.definePropertyProxy(Vue 3)将其定义为响应式属性。每个 computed 属性会创建一个对应的 Watcher 实例,并设置 lazy 标志为 true,表示惰性求值(仅在需要时计算)。

当首次访问 computed 属性时,会触发 getter 函数,执行计算逻辑并缓存结果。计算过程中访问的响应式数据(如 dataprops)会通过依赖收集机制(Dep 类)将当前 Watcher 订阅到这些数据的依赖列表中。

vue computed实现原理

响应式更新

当依赖的响应式数据发生变化时,会通知所有订阅的 Watcher 执行更新。对于 computedWatcher,由于设置了 lazy 标志,不会立即重新计算,而是标记为 dirty(脏数据状态)。

下次访问 computed 属性时,如果 dirtytrue,则重新执行计算逻辑并更新缓存值;否则直接返回缓存值。这种机制确保了不必要的重复计算。

vue computed实现原理

代码示例(简化版)

以下是一个简化的实现逻辑(基于 Vue 2.x 的响应式系统):

class Watcher {
  constructor(vm, fn, options) {
    this.vm = vm;
    this.getter = fn;
    this.lazy = options.lazy;
    this.dirty = this.lazy;
    this.value = this.lazy ? undefined : this.get();
  }

  get() {
    pushTarget(this); // 将当前 Watcher 设置为全局依赖收集目标
    const value = this.getter.call(this.vm);
    popTarget(); // 恢复之前的 Watcher
    return value;
  }

  update() {
    if (this.lazy) {
      this.dirty = true; // 标记为脏数据,下次访问时重新计算
    } else {
      this.get();
    }
  }

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

function defineComputed(vm, key, computeFn) {
  const watcher = new Watcher(vm, computeFn, { lazy: true });

  Object.defineProperty(vm, key, {
    get() {
      if (watcher.dirty) {
        watcher.evaluate(); // 重新计算并更新缓存
      }
      return watcher.value;
    }
  });
}

Vue 3 的优化

在 Vue 3 中,computed 通过 Refeffect 实现,底层基于 ProxyWeakMap 优化依赖追踪。核心逻辑类似,但利用 Composition API 的 reactive 系统提升了性能。

import { reactive, effect } from 'vue';

function computed(getter) {
  let value;
  let dirty = true;

  const runner = effect(getter, {
    lazy: true,
    scheduler: () => {
      dirty = true; // 依赖变更时标记为脏数据
    }
  });

  return {
    get value() {
      if (dirty) {
        value = runner(); // 重新计算
        dirty = false;
      }
      return value;
    }
  };
}

关键点总结

  • 惰性求值:仅在访问时计算,避免不必要的性能开销。
  • 依赖追踪:自动订阅计算函数中使用的响应式数据。
  • 缓存机制:依赖未变化时直接返回缓存值,提升性能。
  • 脏检查:依赖变化后标记为 dirty,下次访问时重新计算。

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

相关文章

vue 实现href

vue 实现href

Vue 实现 href 的方法 在 Vue 中实现 href 功能可以通过多种方式,具体取决于需求场景。以下是几种常见的方法: 使用 <a> 标签 直接使用 HTML 的 <a&g…

vue实现心电图

vue实现心电图

Vue 实现心电图效果 在 Vue 中实现心电图效果通常需要结合 Canvas 或 SVG 进行动态绘图,模拟心电图数据的实时变化。以下是两种实现方式的核心思路和代码示例: 使用 Canvas 绘制…

vue实现pc

vue实现pc

Vue 实现 PC 端应用开发 Vue.js 是一个流行的前端框架,适用于构建 PC 端 Web 应用。以下是关键步骤和最佳实践: 项目初始化 使用 Vue CLI 或 Vite 创建项目:…

vue实现树形

vue实现树形

Vue 实现树形组件 在 Vue 中实现树形结构通常需要递归组件和动态数据绑定。以下是实现树形组件的几种常见方法。 递归组件实现 递归组件是 Vue 中实现树形结构的核心方法。通过组件调用自身,可以…

vue watch实现

vue watch实现

在 Vue 中实现 watch 监听数据变化 Vue 的 watch 选项用于监听数据变化并执行相应的回调函数。以下是几种常见的实现方式: 基础用法 export default { data(…

vue 实现 confirm

vue 实现 confirm

实现确认对话框的方法 在Vue中实现确认对话框可以通过多种方式完成,包括使用内置组件、第三方库或自定义组件。 使用浏览器原生confirm 最简单的实现方式是直接调用浏览器原生的confirm方法。…