vue3.0 watcheffect

2022-05-10  本文已影响0人  如果俞天阳会飞

来源:https://blog.csdn.net/lijiahui_/article/details/123909408

副作用函数的定义

var num = 10
function effect(){
    // 这里只是拿这两个当下例子,讲解的是思想!!并不是什么针对固定的对象。
    document.body.innerText = 'hello vue3';
    num *= 6
}
function fn2(){
    num = 20
    // ...
}

函数effect可以设置body和变量num的内容,但任何其它函数都可以读取 设置这些目标也就是说,effect函数的执行会直接或间接影响其它函数的执行,这时候就可以理解为effect函数产生了副作用。

watchEffect

为了根据响应式状态自动应用 和 重新应用 副作用,我们可以使用 watchEffect 函数。它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
传入的函数就是一个 effect函数 ,它会根据侦听的响应式数据的变化执行该函数。

<script lang='ts' setup>
import { watchEffect,ref,computed } from 'vue';
let count = ref(0)
let Cc = computed(()=> count.value * 2)
let obj = reactive({
  data:123,
  inObj:{d1:0}
})
 
const stop = watchEffect((onInvalidate) => {
  //! 立即执行传入的回调函数,同时响应式追踪其所有依赖,并在依赖变更时重新运行该回调函数。
  console.log(Cc.value); // 注意,如果依赖是 ref 和 computed 对象,必须要.value,否则并不会视为依赖
  console.log(count.value);
  console.log(obj.data); // 同理,reactive数据也只会侦听触发了get的property(属性)
 
 
  //! 注意首次执行并不会执行onInvalidate ,第二次开始才会!
  onInvalidate(()=>{
    //! 在回调触发前会调用该函数,并且stop()停止侦听的时候也会触发一次!
    console.log('watchEffect的onInvalidate');
  })
 
},{
  flush:'pre', // flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
  
  //! 跟踪之前会触发该函数,收集了多少个依赖就触发多少次!返回对应依赖信息
  onTrack(e){console.log(e.target,'onTrack触发')}, 
 
  //! 跟他名字一样依赖更改就触发执行,而且是同步的!没有所谓的缓冲回调
  onTrigger(e){console.log(e.target,'onTrigger触发')} 
})
 
 
setTimeout(() => {
  stop() // 停止侦听 则调用该返回值即可 
}, 1000*5);
 
</script>

停止侦听

const stop = watchEffect(() => {
 
  console.log(obj.data);
})
 
 
setTimeout(() => {
  stop() // 停止侦听 则调用该返回值即可 
}, 1000*5);

清除副作用

在上面的代码中,你细心的话会注意到副作用函数有 onInvalidate 这么个函数参数!

有时副作用函数内会执行一些异步的函数,这些异步响应需要在其失效时清除 (即完成之前状态已改变了) 。所以侦听副作用传入的函数可以接收一个 onInvalidate 函数作入参,用来注册清理失效时的回调。当以下情况发生时,这个失效回调会被触发:

例子一

当 id 数据变更时,导致 token 失效,则调用注销token的方法。

watchEffect(onCleanup => {
  const token = performAsyncOperation(id.value)
  onCleanup(() => {
    // id has changed or watcher is stopped.
    // invalidate previously pending async operation
    token.cancel()
  })
})

例子二

我们之所以是通过传入一个函数去注册某个功能的失效回调,而不是从回调返回它,是因为返回值对于异步错误处理很重要

在执行数据请求时,副作用函数往往是一个异步函数:
当id的值变化快,频繁http请求时,若前面的请求未完成,则会造成重复请求,则可以使用副作用函数的onCleanup参数,取消之前的http请求。

watchEffect(async (onCleanup) => {
  // 返回http请求方法和取消方法(清理函数)
  const { response, cancel } = doAsyncHttpWork(id.value)
 
  onCleanup(cancel) // 注册 取消方法(清理函数)
  data.value = await response // 请求数据
})
上一篇下一篇

猜你喜欢

热点阅读