和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 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都会监听到数据的变化自动执行,每次执行都是获取到变化后的值。
0条评论
点击登录参与评论