浅谈Vue3中watchEffect的具体用法

 更新时间:2022年05月03日 09:06:05   作者:HexOr  
watchEffect,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数,本文主要介绍了Vue3中watchEffect的具体用法,感兴趣的可以了解一下

前言

watchEffect,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。

换句话说:watchEffect相当于将watch 的依赖源和回调函数合并,当任何你有用到的响应式依赖更新时,该回调函数便会重新执行。不同于 watchwatchEffect 的回调函数会被立即执行(即 { immediate: true }

此文主要讲述怎样利用清除副作用使我们的代码更加优雅~

watchEffect的副作用

什么是副作用(side effect),简单的说副作用就是执行某种操作,如对外部可变数据或变量的修改,外部接口的调用等。watchEffect的回调函数就是一个副作用函数,因为我们使用watchEffect就是侦听到依赖的变化后执行某些操作。

当执行副作用函数时,它势必会对系统带来一些影响,如在副作用函数里执行了一个定时器setInterval,因此我们必须处理副作用。 Vue3watchEffect侦听副作用传入的函数可以接收一个 onInvalidate 函数作为入参,用来注册清理失效时的回调。当以下情况发生时,这个失效回调会被触发:

  • 副作用即将重新执行时(即依赖的值改变)
  • 侦听器被停止 (通过显示调用返回值停止侦听,或组件被卸载时隐式调用了停止侦听)
import { watchEffect, ref } from 'vue'

const count = ref(0)
watchEffect((onInvalidate) => {
  console.log(count.value)
  onInvalidate(() => {
    console.log('执行了onInvalidate')
  })
})

setTimeout(()=> {
  count.value++
}, 1000)

上述代码打印的顺序为: 0 -> 执行了onInvalidate,最后执行 -> 1

分析:初始化时先打印count的值0, 然后由于定时器把count的值更新为1, 此时副作用即将重新执行,因此onInvalidate的回调函数会被触发,打印执行了onInvalidate,然后执行了副作用函数,打印count的值1

import { watchEffect, ref } from 'vue'

const count = ref(0)
const stop = watchEffect((onInvalidate) => {
  console.log(count.value)
  onInvalidate(() => {
    console.log('执行了onInvalidate')
  })
})

setTimeout(()=> {
  stop()
}, 1000)

上述代码:当我们显示执行stop函数停止侦听,此时也会触发onInvalidate的回调函数。同样,watchEffect所在的组件被卸载时会隐式调用stop函数停止侦听,故也能触发onInvalidate的回调函数。

watchEffect的应用

利用watchEffect的非惰性执行,以及传入的onInvalidate 函数,我们可以做什么事情了?

场景一:平时我们定义一个定时器,或者监听某个事件,我们需要在mounted生命周期钩子函数内定义或者注册,然后组件销毁之前在beforeUnmount钩子函数里清除定时器或取消监听。这样做我们的逻辑被分散在两个生命周期,不利于维护和阅读。

如果我利用watchEffect,创造和销毁逻辑放在了一起,此时代码更加优雅易读~

// 定时器注册和销毁
watchEffect((onInvalidate) => {
  const timer = setInterval(()=> {
    // ...
  }, 1000)
  onInvalidate(() => clearInterval(timer))
})

const handleClick = () => {
 // ...
}
// dom的监听和取消监听
onMounted(()=>{
  watchEffect((onInvalidate) => {
    document.querySelector('.btn').addEventListener('click', handleClick, false)
    onInvalidate(() => document.querySelector('.btn').removeEventListener('click', handleClick))
  })
})

场景二:利用watchEffect作一个防抖节流(如取消请求)

const id = ref(13)
watchEffect(onInvalidate => {
   // 异步请求
  const token = performAsyncOperation(id.value)
  // 如果id频繁改变,会触发失效函数,取消之前的接口请求
  onInvalidate(() => {
    // id has changed or watcher is stopped.
    // invalidate previously pending async operation
    token.cancel()
  })
})

......

当然watchEffect还能做很多事情,比如打开一个修改的modal弹窗,如果检测到id变化,我们可以在onInvalidate函数内,重置初始参数...这里只是一个抛砖引玉的作用,望大家多多发掘~

相关阅读

Vue3中watch的最佳实践

到此这篇关于浅谈Vue3中watchEffect的具体用法的文章就介绍到这了,更多相关Vue3 watchEffect内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 傻瓜式vuex语法糖kiss-vuex整理

    傻瓜式vuex语法糖kiss-vuex整理

    kiss-vuex 是一个非常简单的语法糖类库,这篇文章主要介绍了傻瓜式vuex语法糖kiss-vuex整理,非常具有实用价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • vue集成高德地图amap-jsapi-loader的实现

    vue集成高德地图amap-jsapi-loader的实现

    本文主要介绍了vue集成高德地图amap-jsapi-loader的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 关于Element Loading的全局使用(自定义Loading)

    关于Element Loading的全局使用(自定义Loading)

    这篇文章主要介绍了关于Element Loading的全局使用(自定义Loading),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Vue过滤器filters的用法及时间戳转换问题

    Vue过滤器filters的用法及时间戳转换问题

    Vue的filters过滤器是比较常见的一个知识点,下面我将结合时间戳转换的例子带你快速了解filters的用法,感兴趣的朋友一起看看吧
    2021-09-09
  • element的表单校验证件号规则及输入“无”的情况校验通过(示例代码)

    element的表单校验证件号规则及输入“无”的情况校验通过(示例代码)

    这篇文章主要介绍了element的表单校验证件号规则及输入“无”的情况校验通过,使用方法对校验数据进行过滤判断,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2023-11-11
  • Vue.js 中的父子组件通信方式实例教程

    Vue.js 中的父子组件通信方式实例教程

    在 Vue.js 中,父子组件通信是非常重要的,在本文中,我们讨论了 Vue.js 中父子组件通信的几种方式,包括使用 props 传递数据、使用 Sync 修饰符实现双向绑定、使用自定义事件传递数据、使用 $refs 访问子组件实例以及使用 $children 和 $parent 访问父子组件实例
    2023-09-09
  • vue3+vite+antd如何实现自定义主题

    vue3+vite+antd如何实现自定义主题

    这篇文章主要介绍了vue3+vite+antd如何实现自定义主题问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue3 SFC 和 TSX 方式自定义组件实现 v-model的详细过程

    Vue3 SFC 和 TSX 方式自定义组件实现 v-model的详细

    v-model 是 vue3 中的一个内置指令,很多表单元素都可以使用这个属性,如 input、checkbox 等,咱可以在自定义组件中实现 v-model,这篇文章主要介绍了Vue3 SFC 和 TSX 方式自定义组件实现 v-model,需要的朋友可以参考下
    2022-10-10
  • vue中el-tree增加节点后如何重新刷新

    vue中el-tree增加节点后如何重新刷新

    这篇文章主要介绍了vue中el-tree增加节点后如何重新刷新,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue键盘事件keyup、keydown的作用

    vue键盘事件keyup、keydown的作用

    这篇文章主要介绍了vue键盘事件keyup、keydown的作用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12

最新评论