setup中使用侦听器
在 vue2 中可以通过 watch 选项来侦听 data、props的数据变化,当数据变化时执行某一些操作。
在 Composition API 中我们可以使用 watchEffect、watch 来完成响应式数据的侦听
watchEffect 用于自动收集响应式数据的依赖;
watch 需要手动指定侦听的数据源;
watchEffect 自动监听
- 首先,watchEffect 传入的函数会被立即执行一次,并且在执行的过程中会收集依赖
- 其次,只有收集的依赖发生变化,watchEffect传入的函数才会再次执行
<template> <div> <h3>{{ count }}</h3> <button @click="increment">+1</button> </div> </template> <script> import { ref, watchEffect } from "vue"; export default { setup() { let count = ref(0); const name = ref("zk"); const age = ref(23); const stopWatch = watchEffect( (onInvalidate) => { console.log( `watchEffect执行~, name:${name.value}, age:${age.value},count:${count.value}` ); /* 我们在开发中可能会遇到在侦听器中去执行网络请求, 但是当网络请求还没有达到的时候,我们想停止侦听器或者侦听器被再次执行了, 那么上一次的网络请求应该被取消掉,这个时候就需要清除上一次的副作用 */ const timer = setTimeout(() => { console.warn("模拟网络请求"); }, 2000); // 侦听器被再次执行或者停止侦听器时的回调 onInvalidate(() => { clearTimeout(timer); }); }, { // 设置watchEffect的执行时机 /* pre : 默认值,在元素挂载或者更新之前执行 post: 在元素挂载之后执行 sync: 强制效果始终同步触发,然而这是低效的,应该避免使用 */ flush: "post", } ); const increment = () => { count.value++; // 如果想要在某个条件下停止侦听,可以调用watchEffect的返回值 if (count.value >= 5) { stopWatch(); } }; return { count, increment, }; }, }; </script>
watch手动监听
与 watchEffect 相比,watch 允许我们:
懒执行副作用(不会立即执行一次)
更具体的说明当哪些状态发生变化时,出发侦听器的执行
访问侦听器数据变化前后的值
watch侦听函数的数据源有两种类型:
一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref)<template> <div> <h2>{{ state.name }}</h2> <button @click="changeName">改变名字</button> </div> </template> <script> import { ref, reactive, watch } from "vue"; export default { setup() { const state = reactive({ name: "zk", age: 23, }); const name = ref("kobe"); // 侦听单个数据源 /* watch 侦听函数的数据源有两种类型: */ watch( () => state.name, (newValue, oldValue) => { console.log( `一个getter函数:newValue:${newValue},oldValue:${oldValue}` ); } ); watch(name, (newValue, oldValue) => { console.log( `一个可响应式对象:newValue:${newValue},oldValue:${oldValue}` ); }); // 侦听多个数据源 watch( () => [state.name, state.age], (newValue, oldValue) => { console.log(`多个数据源:newValue:${newValue},oldValue:${oldValue}`); } ); // 侦听响应式对象 /* 希望侦听一个数组或者对象,那么可以使用getter函数 并且对响应式对象进行解构 */ const letters = reactive(["abc", "cba", "nba"]); watch( () => [...letters], (newValue, oldValue) => { console.log( `侦听响应式对象:newValue:${newValue},oldValue:${oldValue}` ); } ); const changeName = () => { state.name = "张三"; name.value = "李四"; letters.push("ccc"); }; return { state, changeName, }; }, }; </script> <style scoped> </style>