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使用中需要注意的点;说实话,如果没有看过源码的话,这些问题很容易对开发产生影响,所以大家如果没事的时候可以去尝试阅读一下源码
到此这篇关于vue3中的watch使用的文章就介绍到这了,更多相关vue3中watch使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
