computed与 watch的区别

前言

在 Vue 中,computed 和 watch 的功能 —— 一个负责从数据中推导结果一个负责监听数据变化后的反应

核心区别

对比computedwatch
语法简洁✅ 直接返回派生值❌ 需编写回调函数
异步处理❌不支持✅ 支持
自动依赖追踪✅ 自动追踪所有依赖❌ 手动指定监听目标
返回值✅ 必须返回值❌ 不需要返回值
缓存机制✅依赖未变化时,直接返回缓存值❌无缓存,每次变化都触发回调

应用场景

  1. 格式化用户全名
    目标:将 firstName 和 lastName 合并为 fullName
computed: {
  fullName() {
    return `${this.firstName} ${this.lastName}`; 
    // 依赖自动追踪:当 firstName 或 lastName 变化时自动更新
  }
} 

自动追踪依赖:无需手动指定依赖项。
缓存机制:若 firstName 和 lastName 没变,多次访问 fullName 不会重复计算。

  1. 搜索框的联想建议
    目标:当输入框内容变化时,延迟 300ms 调用 API 获取联想词。
watch: {
  searchKeyword: {
    handler(newVal) {
      clearTimeout(this.timer);  // 防抖处理
      this.timer = setTimeout(() => {
        this.fetchSuggestions(newVal);
      }, 300);
    },
    immediate: true // 立即触发一次(初始加载)
  }
} 

支持异步:用于处理如 API 请求等异步逻辑。
手动控制触发时机:通过防抖控制请求频率。

实现原理对比

  1. computed的内部机制
    通过 Watcher 的 dirty 标志实现缓存机制
	class Watcher {
	  constructor(getter) {
	    this.getter = getter;
	    this.dirty = true; // 初始标志为脏数据需要重新计算
	    this.value = null;
	    // 收集依赖...
	  }
	  
	  evaluate() {
	    this.value = this.getter();
	    this.dirty = false; // 计算完成后标志为'干净'
	  }
	  
	  get() {
	    if (this.dirty) {
	      this.evaluate();
	    }
	    return this.value;
	  }
	} 

触发时机: 当依赖的响应式数据变化时,标记 dirty 为 true(下次访问时重新计算)。

  1. watch的执行流程
    利用 Watcher 监听变化并触发回调
	class Watcher {
	  constructor(vm, expOrFn, cb) {
	    this.vm = vm;
	    this.getter = expOrFn; // 例如 () => this.a
	    this.cb = cb;
	    this.value = this.get(); // 初始化时获取初始值
	  }
	
	  update() {
	    const oldValue = this.value;
	    this.value = this.get();
	    this.cb(this.value, oldValue); // 触发回调
	  }
	} 
  • 监听目标数据的 getter 触发依赖收集。
  • 当数据变化时,触发 watcher.update() 执行回调。

总结

何时用computed?何时用watch?
根据响应式数据生成派生值响应数据变化触发副作用(如操作DOM、打印日志)
需要缓存计算结果,避免重复计算需要处理异步或长时间操作(如API请求)
模板中需要简洁的表达式代替复杂计算逻辑需要监听某个数据变化的初始化即时响应( immediate: true )

进阶理解:

  • computed:基于响应式系统中对计算结果优化缓存的理念,适用于类似推导公式的场景。
  • watch:是观察者模式(Observer Pattern)在前端框架中的经典实现,关注的是数据变化的反应动作,类似“监视器”。

computed = 我需要根据已有数据生成新结果
watch = 我要在数据变化后做某些事情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jet_closer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值