当前位置:首页 > VUE

vue computed的实现

2026-01-19 06:02:16VUE

Vue computed 的实现原理

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

初始化 computed 属性

在 Vue 实例初始化阶段,computed 属性会被遍历并转化为 getter/setter 形式。每个 computed 属性会创建一个对应的 Watcher 实例,标记为 lazy(惰性求值)。

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 });
    defineComputed(vm, key, computed[key]);
  }
}

定义 computed 属性

通过 Object.defineProperty 将 computed 属性挂载到 Vue 实例上,并定义 getter/setter:

vue computed的实现

function defineComputed(target, key, userDef) {
  const shouldCache = !isServerRendering();
  if (typeof userDef === 'function') {
    sharedPropertyDefinition.get = shouldCache
      ? createComputedGetter(key)
      : userDef;
    sharedPropertyDefinition.set = noop;
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? shouldCache && userDef.cache !== false
        ? createComputedGetter(key)
        : userDef.get
      : noop;
    sharedPropertyDefinition.set = userDef.set || noop;
  }
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

计算属性的 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 的 evaluate 方法

当依赖变化时(dirty 为 true),会调用 evaluate 重新计算值:

vue computed的实现

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

依赖收集过程

computed 属性在计算时会触发其依赖的响应式数据的 getter,从而建立依赖关系。当依赖变化时,会触发 computed watcher 的 update 方法:

class Watcher {
  update() {
    if (this.lazy) {
      this.dirty = true;
    } else {
      // 其他处理
    }
  }
}

缓存机制

computed 属性只有在依赖变化时才会重新计算(dirty 为 true 时),否则直接返回缓存的值。这是 computed 与 method 的本质区别。

与普通响应式数据的区别

  1. computed 属性是惰性求值的,只有被访问时才会计算
  2. computed 具有缓存机制,依赖不变时直接返回缓存值
  3. computed 的更新是同步的,而 watch 可以是异步的

这种实现方式使得 computed 属性在 Vue 应用中能够高效地处理派生状态,避免不必要的重复计算。

标签: vuecomputed
分享给朋友:

相关文章

jquery实现vue

jquery实现vue

jQuery 和 Vue.js 是两种不同理念的前端工具,jQuery 以 DOM 操作和事件驱动为核心,而 Vue.js 是数据驱动的现代化框架。如果想用 jQuery 实现类似 Vue 的功能(如…

vue实现签章

vue实现签章

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

vue拼图实现

vue拼图实现

实现 Vue 拼图游戏的方法 使用 Vue 组件和动态数据绑定 创建一个 Vue 组件来管理拼图的状态和逻辑。通过 v-for 动态渲染拼图块,利用 v-bind 绑定样式和位置。拼图块的数据可以存储…

vue实现拖拉

vue实现拖拉

实现拖拽功能的基本步骤 在Vue中实现拖拽功能可以通过原生HTML5的拖放API或第三方库如vuedraggable完成。以下是两种方法的详细说明。 使用HTML5原生拖放API HTML5提供了原…

vue 实现 confirm

vue 实现 confirm

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

vue实现列表

vue实现列表

Vue 实现列表的方法 在 Vue 中实现列表渲染通常使用 v-for 指令,可以动态生成多个元素。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 遍历数组,生成列表项。v-for 需要…