watch 监听 reative 创建的值
const state = reactive({ nickname: "xiaofan", age: 20 }); setTimeout(() => { state.age++; }, 800); // 修改age值时会触发 watch的回调 watch( () => state.age, //监听state中的age (newValue, oldValue) => { console.log("新值:", newValue, "老值:", oldValue); } );
watch 监听 ref 创建的值
const year = ref(100); setTimeout(() => { year.value++; }, 1000); watch(() => state.value, (newValue, oldValue) => { console.log("新值:", newValue, "老值:", oldValue); });
watch 监听多个值
const state = ref(100) let person=reactive({ name:'zs' }) setTimeout(() => { state.value++; person.name='李四' }, 800); watch(()=>[state.value, person.name ],([newAge,newName], [oldAge, oldName])=>{ console.log("年龄new:", newAge, "年龄old:", oldAge); console.log("名称new:", newName,"年龄old:", oldName); },); // 如果监听多个对象,第一个函数返回一个数组, //数组中表示监听的值 ()=>[state.value, person.name ] // 第二个匿名函数, ([new1,new2],[old1,old2])=>{ }
watch去监听路由
watch( () => route.fullPath, (n, o) => { console.log('监听路由') console.log('new:' + n + ',old:' + o) } )
watch 的第三个参数 deep:true, immediate: true
watch(() => state.value, (newValue, oldValue) => { console.log("新值:", newValue, "老值:", oldValue); },{ deep: true, immediate: true } ); deep: true 表示开启深度监听。 immediate: true 无论数据是否发生变化,数据默认执行一次 在开启immediate: true。如何值没有发生变化, newValue是初始值 oldValue就是 undefined
如何watch监听
有些时候,当我们监听到数据发生变化后。可能就不需要再次进行监听了。
这个时候我们可以取消监听。
将watch 赋值给一个变量。
let stopWatch=watch(伪代码);
然后需要取消的时候再次调用一次就可以了
stopWatch()
看下面的代码,当我点击取消监听按钮的时候。
就算数据发生变化,watch也会对该数据进行监听了
stop 停止监听watch的监听
<template> <div> <div class="bg"> {{ person }} </div> <a-button @click="changeValue">值发生变化了</a-button> <a-button @click="cancelHander">取消监听</a-button> </div> </template> <script lang="ts"> import { defineComponent, reactive, watch } from 'vue'; export default defineComponent({ setup() { let person=reactive({ name:'zs' }) let changeValue=()=>{ person.name='lisi' } // 修改age值时会触发 watch的回调 let stopWatch=watch( () => person.name, //监听state中的age (newValue, oldValue) => { console.log("新值:", newValue, "老值:", oldValue); } ); // 停止watch监听 let cancelHander=()=>{ stopWatch() } return { cancelHander, person, changeValue, }; }, }); </script>
watchEffect的引入
还有一个监听函数watchEffect,
在我看来watch已经能满足监听的需求,
为什么还要有watchEffect呢?
虽然我没有 get 到它的必要性,
但是还是要介绍一下watchEffect,首先看看它的使用和watch究竟有何不同。
let person=reactive({ name:'zs' }) let state=ref(100) setInterval(()=>{ person.name='我是李四', state.value=1000 },1000) // 修改age值时会触发 watch的回调 watchEffect(()=>{ console.log('state的变化后的值', state.value); console.log('state的变化后的值', person.name); } );
watchEffect发生的现象
执行结果首先打印一次state和name;然后隔一秒后,打印state和name值。
从上面的代码可以看出, 并没有像watch一样需要先传入依赖,
watchEffect会自动收集依赖, 只要指定一个回调函数。
在组件初始化时, 会先执行一次来收集依赖, 然后当收集到的依赖中数据发生变化时,
就会再次执行回调函数。所以总结对比如下:
watchEffect 不需要手动传入依赖
watchEffect 会先执行一次用来自动收集依赖
watchEffect 无法获取到变化前的值, 只能获取变化后的值