当前位置:首页 > VUE

vue computed的实现

2026-02-19 22:24:14VUE

Vue computed 的实现原理

Vue 的 computed 属性是基于响应式依赖进行缓存的计算属性,其实现主要依赖于 Vue 的响应式系统和 Watcher 机制。

核心实现步骤

初始化 computed 属性

在 Vue 实例初始化时,computed 属性会被遍历并定义为响应式属性。每个 computed 属性会创建一个对应的 Watcher 实例,并将 computed 的 getter 函数作为 Watcher 的求值函数。

function initComputed(vm, computed) {
  const watchers = vm._computedWatchers = Object.create(null);
  for (const key in computed) {
    const getter = typeof computed[key] === 'function' 
      ? computed[key] 
      : computed[key].get;
    watchers[key] = new Watcher(
      vm,
      getter,
      noop,
      { lazy: true } // 标记为 computed watcher
    );
    defineComputed(vm, key, computed[key]);
  }
}

定义 computed 属性

通过 Object.defineProperty 将 computed 属性代理到 Vue 实例上,并重写 getter 和 setter。

function defineComputed(target, key, def) {
  const shouldCache = !isServerRendering();
  if (typeof def === 'function') {
    def = { get: def };
  }
  Object.defineProperty(target, key, {
    enumerable: true,
    configurable: true,
    get: shouldCache
      ? createComputedGetter(key)
      : def.get,
    set: def.set || noop
  });
}

computed getter 的实现

当访问 computed 属性时,会触发 getter 函数。该函数会检查依赖是否变化,决定是否重新计算值。

function createComputedGetter(key) {
  return function computedGetter() {
    const watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate(); // 重新计算值
      }
      if (Dep.target) {
        watcher.depend(); // 收集依赖
      }
      return watcher.value;
    }
  };
}

Watcher 的更新机制

computed watcher 在初始化时会被标记为 lazy,首次不会立即求值。当依赖的响应式数据变化时,会触发 watcher 的更新,但不会立即重新计算,而是标记为 dirty,等到下次访问时再重新计算。

class Watcher {
  constructor(vm, expOrFn, cb, options) {
    this.lazy = !!options.lazy;
    this.dirty = this.lazy;
    if (typeof expOrFn === 'function') {
      this.getter = expOrFn;
    }
    this.value = this.lazy ? undefined : this.get();
  }

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

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

关键设计点

缓存机制

computed 属性会根据依赖是否变化来决定是否重新计算。只有当依赖变化时,才会在下一次访问时重新计算,否则直接返回缓存值。

依赖收集

在 computed getter 执行时,会触发依赖的响应式数据的 getter,从而将当前的 computed watcher 收集为依赖。当这些依赖变化时,会通知 computed watcher 更新。

惰性求值

computed 属性在首次访问时才会进行计算,并且只有在依赖变化后再次访问时才会重新计算,这种惰性求值机制提高了性能。

vue computed的实现

标签: vuecomputed
分享给朋友:

相关文章

vue状态管理怎么实现

vue状态管理怎么实现

Vue 状态管理实现方法 使用 Vuex(官方推荐) Vuex 是 Vue 的官方状态管理库,适合中大型应用。 安装 Vuex: npm install vuex --save 创建 Store…

vue实现一个标签选择

vue实现一个标签选择

Vue 标签选择组件实现 基础实现 使用 Vue 的 v-for 和 v-model 指令可以快速实现标签选择功能: <template> <div class="tag-s…

vue实现素材

vue实现素材

Vue 实现素材的方法 使用 Vue 组件管理素材 在 Vue 项目中,可以通过组件化的方式管理素材。创建一个专门的组件来加载和显示素材,例如图片、视频或音频文件。组件可以接收素材的路径或 URL 作…

vue实现签章

vue实现签章

Vue 实现签章功能 签章功能通常包括手写签名、电子印章等。以下是基于 Vue 的实现方法: 使用 canvas 实现手写签名 安装依赖(如需要): npm install signature…

vue实现picker

vue实现picker

Vue 实现 Picker 组件的方法 在 Vue 中实现 Picker 组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 实现 通过 Vue 的模板和样式绑定,…

lua 实现vue

lua 实现vue

在 Lua 中实现类似 Vue 的响应式框架需要模拟 Vue 的核心功能,包括数据绑定、模板渲染和依赖追踪。以下是实现的关键思路和代码示例: 响应式数据绑定 使用 Lua 的 __index 和 _…