vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue computed和watch原理

Vue中的computed和watch的原理解析

作者:BUG 饲养员

Vue的computed和watch都是响应式系统的重要组成部分,computed通过依赖缓存提高性能,而watch用于监听数据变化并执行副作用,两者核心机制不同,而watch则是监听变化并触发回调,本文介绍Vue中的computed和watch的原理,感兴趣的朋友跟随小编一起看看吧

一、核心基础:响应式系统支撑

computed与watch的实现均依赖Vue响应式核心——依赖收集与触发更新

二者本质是响应式系统的“上层应用”,差异在于对依赖变化的处理逻辑。

二、computed:带缓存的依赖推导

2.1 核心原理:缓存+懒执行

computed是“派生值”计算器,核心特性是依赖不变则复用缓存,避免重复计算:

2.2 简化实现代码

// 模拟computed核心逻辑(Vue3风格)
class ComputedRef {
  constructor(getter, ctx) {
    this.getter = getter; // 计算函数
    this.ctx = ctx; // 上下文
    this._value = null; // 缓存值
    this._dirty = true; // 脏标记:true需重新计算
  }
  // 访问computed时触发
  get value() {
    if (this._dirty) {
      this._value = this.getter.call(this.ctx); // 执行计算
      this._dirty = false; // 标记为清洁
    }
    return this._value; // 复用缓存
  }
  // 依赖变化时调用
  markDirty() {
    this._dirty = true; // 标记为脏
  }
}
// 实际使用
const count = ref(1);
// 计算属性:依赖count
const doubleCount = new ComputedRef(() => count.value * 2, this);
console.log(doubleCount.value); // 2(计算并缓存)
console.log(doubleCount.value); // 2(直接复用缓存)
count.value = 2; // 触发count的setter,调用doubleCount.markDirty()
console.log(doubleCount.value); // 4(重新计算)

三、watch:数据变化的副作用触发器

3.1 核心原理:监听变化+执行回调

watch是“数据监听器”,核心是监听指定数据源变化,触发自定义副作用(如异步请求、DOM操作),支持深度监听和立即执行。

3.2 关键特性与实现

// 模拟watch核心逻辑(Vue3风格)
function watch(source, callback, options = {}) {
  const { immediate = false, deep = false } = options;
  let oldValue;
  // 1. 初始化:获取初始值
  const getInitialValue = () => {
    // 深度监听时递归收集对象所有属性依赖
    if (deep && isObject(source.value)) {
      traverse(source.value);
    }
    return source.value;
  };
  // 2. 副作用函数:数据变化时执行
  const effectFn = () => {
    const newValue = source.value;
    callback(newValue, oldValue); // 触发回调
    oldValue = newValue;
  };
  // 3. 立即执行(immediate为true时)
  if (immediate) {
    oldValue = getInitialValue();
    effectFn();
  } else {
    oldValue = getInitialValue();
  }
  // 4. 关联响应式数据:依赖变化时触发effectFn
  effect(effectFn, { lazy: false });
}
// 实际使用
const user = reactive({ name: '张三', age: 20 });
// 监听user.age,支持深度监听
watch(
  () => user.age,
  (newAge, oldAge) => {
    console.log(`年龄从${oldAge}变为${newAge}`);
  },
  { immediate: true, deep: false }
);

深度监听(deep: true)通过递归遍历对象属性实现,会收集所有子属性依赖,性能消耗较高,非必要不使用。

四、核心差异与适用场景

维度computedwatch
核心机制依赖推导,缓存结果监听变化,触发副作用
缓存特性有缓存,依赖不变不计算无缓存,变化即触发
返回值必须返回值(派生数据)无需返回值(执行操作)
适用场景数据格式化、多值计算(如总价=单价×数量)异步操作、数据变化后的复杂逻辑(如刷新列表)

五、实战避坑要点

到此这篇关于Vue中的computed和watch的原理解析的文章就介绍到这了,更多相关vue computed和watch原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文