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

vue computed的实现

当访问 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();
    }
  }
}

关键设计点

缓存机制

vue computed的实现

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

依赖收集

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

惰性求值

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

标签: vuecomputed
分享给朋友:

相关文章

vue 实现全选

vue 实现全选

Vue 实现全选功能 在 Vue 中实现全选功能通常需要结合复选框的状态管理,以下是几种常见的实现方式: 使用 v-model 绑定数组 通过 v-model 绑定一个数组来管理选中的项,全…

vue实现画图

vue实现画图

Vue 实现画图功能 在 Vue 中实现画图功能通常需要结合 HTML5 的 <canvas> 元素或第三方库。以下是几种常见的方法: 使用原生 Canvas API 通过 Vue 直接…

vue el 实现

vue el 实现

Vue 中使用 Element UI (el) 的实现方法 Element UI 是一个基于 Vue 的组件库,提供丰富的 UI 组件,常用于快速构建企业级中后台产品。以下介绍 Vue 项目中集成和使…

vue课程实现

vue课程实现

Vue 课程实现方案 课程内容设计 Vue课程应从基础到高级逐步展开,涵盖Vue核心概念、组件化开发、状态管理、路由、构建工具等。基础部分包括Vue实例、模板语法、计算属性和侦听器。中级部分深入组件通…

tabbar 实现 vue

tabbar 实现 vue

在 Vue 中实现 TabBar 功能可以通过多种方式完成,以下是几种常见的方法: 使用 Vue Router 结合自定义组件 创建一个自定义的 TabBar 组件,结合 Vue Router 实现…

vue jwt实现

vue jwt实现

Vue JWT 实现方法 安装依赖 确保项目中安装了 jsonwebtoken(后端)和 axios(前端)。若使用 Vue 3,可搭配 vue-router 和 pinia(或 vuex)管理状态。…