当前位置:首页 > VUE

vue computed实现原理

2026-02-18 18:03:27VUE

Vue computed 实现原理

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

依赖收集与缓存

computed 属性通过 Object.definePropertyProxy(Vue 3)将其定义为响应式属性。每个 computed 属性会创建一个对应的 Watcher 实例,并设置 lazy 标志为 true,表示惰性求值(仅在需要时计算)。

当首次访问 computed 属性时,会触发 getter 函数,执行计算逻辑并缓存结果。计算过程中访问的响应式数据(如 dataprops)会通过依赖收集机制(Dep 类)将当前 Watcher 订阅到这些数据的依赖列表中。

vue computed实现原理

响应式更新

当依赖的响应式数据发生变化时,会通知所有订阅的 Watcher 执行更新。对于 computedWatcher,由于设置了 lazy 标志,不会立即重新计算,而是标记为 dirty(脏数据状态)。

下次访问 computed 属性时,如果 dirtytrue,则重新执行计算逻辑并更新缓存值;否则直接返回缓存值。这种机制确保了不必要的重复计算。

vue computed实现原理

代码示例(简化版)

以下是一个简化的实现逻辑(基于 Vue 2.x 的响应式系统):

class Watcher {
  constructor(vm, fn, options) {
    this.vm = vm;
    this.getter = fn;
    this.lazy = options.lazy;
    this.dirty = this.lazy;
    this.value = this.lazy ? undefined : this.get();
  }

  get() {
    pushTarget(this); // 将当前 Watcher 设置为全局依赖收集目标
    const value = this.getter.call(this.vm);
    popTarget(); // 恢复之前的 Watcher
    return value;
  }

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

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

function defineComputed(vm, key, computeFn) {
  const watcher = new Watcher(vm, computeFn, { lazy: true });

  Object.defineProperty(vm, key, {
    get() {
      if (watcher.dirty) {
        watcher.evaluate(); // 重新计算并更新缓存
      }
      return watcher.value;
    }
  });
}

Vue 3 的优化

在 Vue 3 中,computed 通过 Refeffect 实现,底层基于 ProxyWeakMap 优化依赖追踪。核心逻辑类似,但利用 Composition API 的 reactive 系统提升了性能。

import { reactive, effect } from 'vue';

function computed(getter) {
  let value;
  let dirty = true;

  const runner = effect(getter, {
    lazy: true,
    scheduler: () => {
      dirty = true; // 依赖变更时标记为脏数据
    }
  });

  return {
    get value() {
      if (dirty) {
        value = runner(); // 重新计算
        dirty = false;
      }
      return value;
    }
  };
}

关键点总结

  • 惰性求值:仅在访问时计算,避免不必要的性能开销。
  • 依赖追踪:自动订阅计算函数中使用的响应式数据。
  • 缓存机制:依赖未变化时直接返回缓存值,提升性能。
  • 脏检查:依赖变化后标记为 dirty,下次访问时重新计算。

标签: 原理vue
分享给朋友:

相关文章

vue实现菜单

vue实现菜单

Vue 实现菜单的方法 在 Vue 中实现菜单功能可以通过多种方式完成,以下是几种常见的方法: 使用 v-for 动态生成菜单项 通过数据驱动的方式,利用 v-for 指令动态渲染菜单项。定义一个…

vue实现遮罩

vue实现遮罩

Vue 实现遮罩层的方法 在 Vue 中实现遮罩层可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 v-show 或 v-if 控制显示 通过 Vue 的指令动态控制遮罩层的显示与隐藏。…

vue 实现关闭

vue 实现关闭

Vue 实现关闭功能的方法 在Vue中实现关闭功能通常涉及组件销毁、模态框隐藏或路由跳转等场景。以下是几种常见实现方式: 销毁当前组件 使用v-if或v-show控制组件显示/隐藏,适用于局部组件…

分页实现vue

分页实现vue

分页实现(Vue) 在Vue中实现分页功能通常需要结合前端分页逻辑和后端API支持。以下是两种常见的实现方式: 前端分页实现 适用于数据量较小的情况,直接在客户端完成分页逻辑。 <tem…

vue实现曲线

vue实现曲线

Vue 实现曲线的方法 在 Vue 中实现曲线可以通过多种方式,包括使用 SVG、Canvas 或第三方库如 D3.js、ECharts 等。以下是几种常见的方法: 使用 SVG 绘制曲线 SVG…

vue首页实现

vue首页实现

实现Vue首页的基本步骤 创建一个Vue首页通常涉及项目初始化、页面结构设计、路由配置和组件开发。以下是具体实现方法: 初始化Vue项目 使用Vue CLI或Vite快速搭建项目结构: np…