vue3中 watch、watchEffect区别

通过官网上的介绍得出如下简单的结论

1、watch是惰性执行,也就是只有监听的值发生变化的时候才会执行,但是watchEffect不同,每次代码加载watchEffect都会执行(忽略watch第三个参数的配置,如果修改配置项也可以实现立即执行)
2、watch需要传递监听的对象,watchEffect不需要
3、watch只能监听响应式数据:ref定义的属性和reactive定义的对象,如果直接监听reactive定义对象中的属性是不允许的(会报警告),除非使用函数转换一下。其实就是官网上说的监听一个getter
4、watchEffect如果监听reactive定义的对象是不起作用的,只能监听对象中的属性。

先看一下watchEffect的代码,验证一下




看下图可以看到。
image.png

image.png

改造一下代码





image.png




image.png

稍微改造一下

watchEffect(()=>{
      console.log('触发了watchEffect');
      console.log(obj.text);
    })
image.png
再看一下watch的代码,验证一下



配置immediate参数,立即执行,以及深层次监听

// 配置immediate参数,立即执行,以及深层次监听
 watch(obj, (newValue, oldValue) => {
      // 回调函数
      console.log('触发监控更新了new',  newValue);
      console.log('触发监控更新了old',  oldValue);
    }, {
      immediate: true,
      deep: true
    })
image.png
监控整个reactive对象,从上面的图可以看到 deep 实际默认是开启的,就算我们设置为false也还是无效。而且旧值获取不到。

要获取旧值则需要监控对象的属性,也就是监听一个getter,看下图


image.png

正确的写法,运行之后看下图


image.png

总结:

  • 如果定义了reactive的数据,想去使用watch监听数据改变,则无法正确获取旧值,并且deep属性配置无效,自动强制开启了深层次监听。
  • 如果使用 ref 初始化一个对象或者数组类型的数据,会被自动转成reactive的实现方式,生成proxy代理对象。也会变得无法正确取旧值。
  • 用任何方式生成的数据,如果接收的变量是一个proxy代理对象,就都会导致watch这个对象时,watch回调里无法正确获取旧值。

所以当大家使用watch监听对象时,如果在不需要使用旧值的情况,可以正常监听对象没关系;但是如果当监听改变函数里面需要用到旧值时,只能监听 对象.xxx属性 的方式才行。

详细说明请移步这里大佬们说的非常好 点击传送门

你可能感兴趣的:(vue3中 watch、watchEffect区别)