当前位置:首页 > 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:

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 重新计算值:

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 的本质区别。

vue computed的实现

与普通响应式数据的区别

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

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

标签: vuecomputed
分享给朋友:

相关文章

vue实现定位

vue实现定位

Vue 中实现定位的方法 在 Vue 中实现定位可以通过以下几种方式: 使用 CSS 定位 通过 CSS 的 position 属性实现定位,Vue 中可以直接在组件的 <style>…

vue实现数组

vue实现数组

Vue 实现数组操作的方法 在 Vue 中,数组的操作需要特别注意响应式的问题。Vue 提供了一些方法来确保数组的变动能够触发视图更新。 响应式数组方法 Vue 对以下数组方法进行了封装,确保它们能…

vue diff实现

vue diff实现

Vue Diff 算法实现原理 Vue 的虚拟 DOM Diff 算法(即 patch 过程)是其高效渲染的核心,主要通过对比新旧虚拟节点的差异,最小化 DOM 操作。以下是关键实现要点: 同层级比…

vue 菜单实现

vue 菜单实现

Vue 菜单实现方法 在Vue中实现菜单功能可以通过多种方式完成,以下是几种常见的实现方法: 使用v-for动态生成菜单 通过数据驱动的方式动态渲染菜单项,适合菜单内容可能变化的场景: <t…

vue实现注册

vue实现注册

Vue 实现注册功能 注册功能通常涉及前端表单、数据验证、与后端 API 的交互等步骤。以下是一个完整的 Vue 实现注册功能的方案。 创建注册表单 使用 Vue 的模板语法创建注册表单,包含用户名…

vue实现listview

vue实现listview

Vue 实现 ListView 的方法 基础列表渲染 使用 v-for 指令可以轻松实现基础列表渲染。在 Vue 中,v-for 用于遍历数组或对象,生成动态列表。 <template>…