【Vue3】computed、watch、watchEffect 横向对比

先比较一下

三者都是侦听工具,实现的是观察者模式,所以我们可以把三者放在一起,做一下横向对比,辅助大家理解。

 

对比依据 computed watch watchEffect
是否自动收集依赖(1) 自动 需要指定依赖对象 自动
有无返回值
是否可以赋值 可以 不能 不能
使用场景 简单情况 复杂情况 简单情况
是否立即执行 看参数(2)
本质 class function function

 

  • (1)依赖:指的是响应性依赖,也就是侦听 ref、reactive 这类具有响应性的对象。
  • (2)watch:默认情况下,被侦听对象变化时才会执行,但是可以通过 options 参数设置为可以立即执行

1、computed

computed 这个单词比较有误导性,看表面是计算用的,但是除了计算之外还可以有其他的功能,比如做个判断、做个序列化、赋值等。

但这些都不是重点,重点是,它和 watch 一样,是侦听用的。

自动侦听 getter 里有响应性的对象,当发生变化时重新执行一次 get 函数,将返回结果存入 _value 缓存,并且通知 template 刷新页面。

所以说,计不计算的不是重点,侦听才是重点。

(1)基础示例

举个例子,我想在网页里看看对象的序列化,用 computed 的实现方式:

 

 

image

 

定义一个 reactive 和 一个 computed,使用 JSON.stringify 实现序列化。

 

image

 

自动收集依赖,侦听 model 的变化,序列化之后交给 template 的 el-input。

这样我们就可以在网页里面实时看到对象的序列化情况了。

(2)结构和本质

我们打印一下 computed ,看看结构:

 

image

 

看起来挺复杂的,其实简化一下就简单了,主体是一个 class,其中有若干“私有成员”,然后用访问器实现我们常用的 value 属性,即:

 

 

image

 

主要结构是这样,当然还需要很多细节才能实现 computed 的功能,如果对细节感兴趣的话,可以看看 Vue 的源码。

(3)计算属性缓存

其实看看源码就好理解了,执行 get 方法时,会把返回值存入 _value ,template 直接从 _value 属性获取数据,在需要更新缓存的时候才会调用 getter,这样就实现了缓存功能。

也就是说,使用 _value 属性缓存了执行结果。

(4)可以赋值的方式

computed 也可以开启赋值模式,方法就是传入一个对象,拥有 get 和 set 的对象,可以用在 props 在模板上的绑定。

props 的属性是只读的,不能用于 template 的 v-model,那么怎么办?我们可以使用 computed 的赋值模式作为中转站:

  • 子组件:

 

 

image

 

在子组件里面定义 props 和 emit,然后可以用computed实现“中转”功能,get 里面获取 props 的属性值,set 里面使用 emit 提交更改申请。

当然,现在 Vue3.3+ 推出了语法糖 defineModel,就不需要我们自己折腾了。

2、watch

composition API 的 watch 非常好理解,他是一个函数,第一个参数要指定一个被侦听对象,第二个参数是回调函数,在被侦听的对象发生变化时,执行回调函数。(当初看option 的watch,怎么看都看不懂。。。)

(1)基础示例

还是上面那个例子,我们看看用 watch 如何实现:(watch 并不适合实现这样的需求,这里仅做对比)

 

image

 

我们先定义一个 ref,然后用 watch 侦听 model,发生变化的时候再做序列化的操作,给 ref 赋值。

对比一下就会发现,对于这种简单的需求,使用 watch 明显没有使用 computed 方便。

不过 watch 可以明确指定侦听的对象,这样对于复杂的情况就不容易乱,不用担心自动收集依赖,把不想被侦听的对象也给收集进来。

watch的更多用法可以看看官网

3、watchEffect

一开始没弄明白 watchEffect,后来把三者放在一起一对比就好懂了。

  • 和 computed 对比,相当于没有返回值的 computed,当然也不能 set。
  • 和 watch 对比,可以自动收集依赖,无需手动指定。

这样想就清晰了,排列组合的结果。

是否自动收集依赖、是否有返回值组合一下,

  • 自动收集依赖、无返回:watchEffect
  • 自动收集依赖、有返回:computed
  • 需要指定依赖、无返回:watch

那么需要指定依赖,还有返回的是谁呢?好像没有。。。

(1)基础示例

还是上面那个例子:

 

image

 

不需要自定侦听对象,而是像computed那样可以自动收集,然后还是当model变化时执行序列化的操作,赋值给 ref。

官网的例子只有一个 console.log ,还以为只是做调试用的呢。。。

当然 watchEffect 还有其的功能,比如停止侦听等,这里就不细说了,可以看看官网。

posted @ 2026-07-03 10:15  蓦然JL  阅读(10)  评论(0)    收藏  举报
访问主页
关注我
关注微博
私信我
返回顶部