正文
watchEffect简单来说就是指名监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
但是它会有一个副作用。举个简单的例子就是,当你监听一个input的值,一旦值改变就调用一次接口,那么我们多次改变值时对应的接口请求也是多次的,这就会造成性能浪费。而在watchEffect里面进行监听触发接口时,如果该接口还没请求完,但是input值已经变更了,那么我们就要把这个未完成的接口(异步任务)清除掉,进而调用一个新的接口。
是的,简单来说副作用就是未完成的异步任务(包括setTimeout等)。
因此清除副作用就是清除掉未完成的异步任务进而调用下一次的watchEffect。
嗅觉灵敏的人就会发现,所谓的清除副作用就跟防抖里面的清除定时器变量一个道理。
所以我们可以用watchEffect来实现防抖机制,代码如下:
PS:onInvalidate是watchEffect回调函数里面的参数,作用就是清除副作用。
<script setup>
import { ref, watchEffect } from "vue";
let input = ref(0);
const getData = function(){
return new Promise((resolve)=>{
resolve('返回的数据');
})
}
const stop = watchEffect((onInvalidate)=>{
console.log('input的值增加了,将调用接口',input.value);
let timer = setTimeout( async() => {
let res = await getData();
console.log(res)
},2000);
// 清除副作用:onInvalidate
onInvalidate(()=>{
clearTimeout(timer);
console.log('接口还没调用成功 input的值有变动了 取消接口请求 再次触发watchEffect');
if(input.value>9) clearInterval(inter);
})
})
let inter = setInterval(()=>{
input.value++;
},1000)
// 停止监听
onBeforeUnmount(() => {
stop();
})
</script>