vue3中的watch采用

前言

前段时间看了一些直播关于vue3中的watch的使用,有许多看起来比较难以理解东西,今天就举几个例子看看兄弟们watch的实际掌握情况

二、案例

tips 以下除开特殊说明,修改的内容都是setTimeout里面的赋值操作

1.案例1

<script setup lang="ts">
  import { watch, ref } from "vue";
  let obj: any = ref({ a: 1, b: { c: 1 } });
  watch(
  obj,
  (newVal, oldVal) => {
  console.log(newVal, oldVal);
  },
  { deep: true }
  );
  setTimeout(() => {
  obj = { a: 2 }
  console.log("修改数据");
  }, 1000);
  </script>
    <template></template>
      <style scoped>
        .read-the-docs {
        color: #888;
        }
        </style>

这一种相信大家可能比较清楚,肯定是不会触发watch的执行
在这里插入图片描述

2.案例2

修改赋值操作为 obj.value = { a: 2 } 结果是会触发watch的执行
在这里插入图片描述
为什么呢:因为在源码当中watch如果第一个参数是ref,那么源码会将其转换成
getter = () => source.value; 即watch判断的是ref.value有没有发生变化,很明显,这个案例是发生了变化,所以watch会执行

3.案例3

修改赋值操作为 obj.value.a = 2 这个会不会呢
可能有的小伙伴看到案例2的解释觉得不会,但是错误,因为这里有一个配置项:deep:true
当开启这个选项的时候,就会递归收集,那么相当于obj.value的对象也被监听了,所以会触发
在这里插入图片描述
但是当你把deep:true改成false或者不做配置就不会

4.案例4

watch(
() => obj,
(newVal, oldVal) => {
console.log(newVal, oldVal);
}
);

只改变地第一个参数的传递方式,其他不变,当然deep这个参数取消了,那么以上的几种方式会触发执行吗
很遗憾告诉大家,一个都不会触发
在这里插入图片描述
这里就涉及到watch第一个参数传参的方式了:
如果当传的是一个函数,那么vue不会对这个函数做处理,监听的也是这个函数的返回值,相当于你监听的是这个obj,而不是obj.value,而响应式拦截是需要监听数据,即在这里如果想实现修改变化,需要监听的是obj.value
但是当deep设置为true时,结果又不一样了
除了obj = { a: 2 } 不会重新触发,其他都会触发,是因为deep:true会递归收集依赖,所以修改都会变化

5.案例5

watch(
obj.value,
(newVal, oldVal) => {
console.log(newVal, oldVal);
},
);

这里又不一样了,第一个参数是obj.value
那么obj.value.a = 2会不会触发执行呢?
答案是会!
在这里插入图片描述
解释一下:此时第一个参数obj.value,其实就相当于第一个参数是reactive,你修改reactive的属性的值,肯定是会触发重新执行的

6.案例6

修改赋值为obj = { a: 2 } 答案肯定是不会重新触发的,对象的地址都发生了变化,不再是原来那个对象了,当时你设置obj.value = {a:2} 是一样的

7. 案例7

修改obj.b.c = 2 呢,会重新触发,因为watch监听reactive默认deep:true,默认进行深度监听
在这里插入图片描述

总结

以上就是关于watch使用中需要注意的点;说实话,如果没有看过源码的话,这些问题很容易对开发产生影响,所以大家如果没事的时候可以去尝试阅读一下源码
当然文章有问题欢迎指出

posted @ 2026-01-26 21:41  clnchanpin  阅读(3)  评论(0)    收藏  举报