和computed相对应的就是watch,computed是多对一的关系,而watch则是一对多的关系;vue3也提供了两个函数来侦听数据源的变化:watch和watchEffect。
我们先来看下watch,它的用法和组件的watch选项用法完全相同,它需要监听某个数据源,然后执行具体的回调函数,我们首先看下它监听单个数据源的用法:
import { reactive, ref, watch } from "vue";
const state = reactive({
count: 0,
});
//侦听时返回值得getter函数
watch(
() => state.count,
(count, prevCount) => {
// 1 0
console.log(count, prevCount);
}
);
state.count++;
const count = ref(0);
//直接侦听ref
watch(count, (count, prevCount) => {
// 2 0
console.log(count, prevCount, "watch");
});
count.value = 2;
我们也可以把多个值放在一个数组中进行侦听,最后的值也以数组形式返回:
const state = reactive({
count: 1,
});
const count = ref(2);
watch([() => state.count, count], (newVal, oldVal) => {
//[3, 2] [1, 2]
//[3, 4] [3, 2]
console.log(newVal, oldVal);
});
state.count = 3;
count.value = 4;
如果我们来侦听一个深度嵌套的对象属性变化时,需要设置deep:true
:
const deepObj = reactive({
a: {
b: {
c: "hello",
},
},
});
watch(
() => deepObj,
(val, old) => {
// new hello new hello
console.log(val.a.b.c, old.a.b.c);
},
{ deep: true }
);
deepObj.a.b.c = "new hello";
最后的打印结果可以发现都是改变后的值,这是因为侦听一个响应式对象始终返回该对象的引用,因此我们需要对值进行深拷贝:
import _ from "lodash";
const deepObj = reactive({
a: {
b: {
c: "hello",
},
},
});
watch(
() => _.cloneDeep(deepObj),
(val, old) => {
// new hello new hello
console.log(val.a.b.c, old.a.b.c);
},
{ deep: true }
);
deepObj.a.b.c = "new hello";
一般侦听都会在组件销毁时自动停止,但是有时候我们想在组件销毁前手动的方式进行停止,可以调用watch返回的stop函数进行停止:
const count = ref(0);
const stop = watch(count, (count, prevCount) => {
// 不执行
console.log(count, prevCount);
});
setTimeout(()=>{
count.value = 2;
}, 1000);
// 停止watch
stop();
还有一个函数watchEffect也可以用来进行侦听,但是都已经有watch了,这个watchEffect和watch有什么区别呢?他们的用法主要有以下几点不同:
- watchEffect不需要手动传入依赖
- 每次初始化时watchEffect都会执行一次回调函数来自动获取依赖
- watchEffect无法获取到原值,只能得到变化后的值
import { reactive, ref, watch, watchEffect } from "vue";
const count = ref(0);
const state = reactive({
year: 2021,
});
watchEffect(() => {
console.log(count.value);
console.log(state.year);
});
setInterval(() => {
count.value++;
state.year++;
}, 1000);
watchEffect会在页面加载时自动执行一次,追踪响应式依赖;在加载后定时器每隔1s执行时,watchEffect都会监听到数据的变化自动执行,每次执行都是获取到变化后的值。
说完响应式侦听,下期我们开始说 组合API。
感觉有用请点赞关注本人博客👇