当前位置:首页 > 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
分享给朋友:

相关文章

vue 实现手册

vue 实现手册

以下是关于 Vue.js 实现手册的整理内容,涵盖核心概念、实践方法和常见场景的解决方案: 核心概念与基础用法 Vue.js 是一个渐进式 JavaScript 框架,核心特点包括数据驱动视图和组件…

vue实现适老化样式

vue实现适老化样式

Vue 实现适老化样式的关键方法 全局字体与字号调整 通过 CSS 变量或主题配置统一放大基础字号,建议正文不小于 18px,标题更大。在 App.vue 中设置全局样式: :root { --…

vue实现导航切换内容

vue实现导航切换内容

Vue实现导航切换内容的方法 在Vue中实现导航切换内容,可以通过以下方式实现: 使用动态组件 动态组件通过<component :is="currentComponent">实现内容切…

vue实现上移下移插件

vue实现上移下移插件

实现上移下移功能的 Vue 插件 在 Vue 中实现列表项的上移和下移功能,可以通过自定义指令或组件封装的方式完成。以下是两种常见实现方式: 基于数组操作的通用方法 通过操作数组索引实现元素位置交…

vue实现生成二维码

vue实现生成二维码

使用qrcode.vue库生成二维码 安装qrcode.vue库: npm install qrcode.vue --save 在Vue组件中使用: <template> &l…

vue实现store

vue实现store

Vue 实现 Store 在 Vue 中,可以通过 Vuex 或 Pinia 实现全局状态管理(Store)。以下是两种主流方案的实现方法。 使用 Vuex 实现 Store Vuex 是 Vue…