在了解 `watchEffect` api之前,需要了解在vue中,副作用函数的定义是什么:

字面意义的讲,副作用函数指的是会产生副作用的函数,例如下面该函数:

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

函数 effect 可以设置body和变量num的内容,但任何其他函数都可以读取、设置这些目标,也就是说,effect 函数的执行会直接或间接影响其他函数的执行,这时候就可以理解为effect函数产生了副作用。【案例和简要的说明来自(vue.js 设计与实现)该书】

在vue的底层设计中,effect 函数的运用概念挺多的。像vue的响应式设计就蕴含着该概念。


# watchEffect

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

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

注意,响应式数据必须要触发get才能劫持对应的内容为该副作用函数的依赖。

  • watchEffect 接收2个参数 ,并且有返回一个 StopHandle 函数用来停止侦听。

    • 1、第一个参数:(必传)
      effect 函数,收集依赖,并且组件初始化时立即执行一次;
      并且 effect 函数可以接受一个 onInvalidate 函数参数,该参数执行并传入一个 callback ,每次监听回调执行前都会执行该 callback。
    • 2、第二个参数对象(非必传): flush 、 onTrack 、 onTrigger; 
      flush 跟 watch() $watch() watch:{} 的flush 完全一致。同理也具备 <缓冲回调>
      onTrack 、 onTrigger 看代码写的注释讲解!

      • 关于 `flush` 请查看我其他watch的文章,watch使用方法上讲的很细,这么好竟然没人看?
<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 函数作入参,用来注册清理失效时的回调。当以下情况发生时,这个失效回调会被触发:

  • 副作用即将重新执行时
  • 侦听器被停止 (如果在 setup() 或生命周期钩子函数中使用了 watchEffect,在组件卸载时会自动停止侦听。)

例子1:

当 id 数据变更时,导致 token 失效,则调用注销token的方法。(这只是个例子,请融会贯通,举一反三!谢谢)

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

例子2: 这个例子讲解会更清晰点。。

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


在执行数据请求时,副作用函数往往是一个异步函数:
当id的值变化快,频繁http请求时,若前面的请求未完成,则会造成重复请求,则可以使用副作用函数的onCleanup参数,取消之前的http请求。
(叫啥都行,不过统一下较好,onCleanup是vue3最新版英文官网的名字定义)

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

# watchPostEffect   watchSyncEffect 就不讲了,不懂说明你根本不懂flush参数的作用,请移步我watch的文章。

watchSyncEffect 为例,简单讲就是除了 flush 参数固定为 'sync' ,其他所有功能跟 watchEffect 一样。

watchPostEffect  v3.2+

watchEffect 的别名,固定 flush: 'post' 选项。

watchSyncEffect  v3.2+

watchEffect 的别名,固定 flush: 'sync' 选项。


QQ交流群:522976012  ,欢迎来玩。

聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。

【vue3 Api - watchEffect 的讲解 使用】- 侦听响应式数据执行副作用(effect)函数相关推荐

  1. Vue3官网-高级指南(十七)响应式计算`computed`和侦听`watchEffect`(onTrack、onTrigger、onInvalidate、副作用的刷新时机、`watch` 、pre)

    Vue3官网-高级指南(十七)响应式计算computed和侦听watchEffect(onTrack.onTrigger.onInvalidate.副作用的刷新时机.watch .pre).渲染机制和 ...

  2. Vue响应式数据基本讲解(2.0和3.0)

    响应式数据 一.何为响应式 在我们的程序中,总是需要去修改JS变量中的数据,然后使得页面中的内容也跟着变化,如下面的代码 <body><p>姓氏: <span class ...

  3. vue3之实现响应式数据ref和reactive

    用途 ref.reactive都是vue3提供实现响应式数据的方法 ref() 接受一个内部值,返回一个响应式的.可更改的ref对象,此对象只有一个指向其内部的属性.value ref可以说是简化版的 ...

  4. java从外部得到数据_java – 如何实现Observer以从侦听器获取数据?

    我正在使用 MaterialDrawer库为我的应用程序创建一个简单的抽屉,库中的一些类实例需要在调用时传递给它们的字符串.一个例子是IProfile类: IProfile profile = new ...

  5. 《vue3+TS+element-plus 后端管理系统系列》之响应式设计

    vue3-composition-admin 是一个管理端模板解决方案,它是基于vue3,ts和element-plus,项目都是以composition api风格编写. 演示地址:https:// ...

  6. vue3.0初体验(例子解读reactive响应式)

    目录 准备 vue3 reactive原理例子重点讲解 vue3 reactive原理例子完整代码 准备: 下载vue-next 安装依赖 npm install 核心部分package,里面的vue ...

  7. Vue3通透教程【五】Vue3中的响应式数据 reactive函数、ref函数

    文章目录

  8. 04 【计算属性 侦听器】

    9.计算属性 有时我们需要依赖于其他状态(普通proxy响应式数据)的状态(computed响应式数据): 在 Vue 中,这是用组件计算属性处理的,以直接创建计算值,我们可以使用 computed ...

  9. Vue响应式原理详细讲解

    面试官:请你简单的说说什么是Vue的响应式. 小明:mvvm就是视图模型模型视图,只有数据改变视图就会同时更新. 面试官:说的很好,回去等通知吧. 小明:.... Vue响应式原理 先看官方的说法 简 ...

最新文章

  1. mysql从当前月向前推12_JavaScript获取当前时间向前推三个月的方法示例
  2. 数学建模学习笔记——分类模型
  3. 与顶级互联网公司技术大佬面对面聊聊RocketMQ
  4. nexus-3本地下载jar的settipng.xml配置
  5. unc 隐藏共享文件夹_你真的了解任务栏吗?win10任务栏居然隐藏了这么多小窍门...
  6. Integer缓存池
  7. es6生成器_ES6生成器
  8. mfc遍历指定文件夹下的所有文件并排序
  9. 开发框架-移动开发平台: mPaaS
  10. Java正则表达式中,group()、group(i)、groupCount()含义详解
  11. neo4j java 模糊搜索,Neo4j 使用cypher语言进行查询
  12. 【SCIR笔记】ACL2020表格预训练工作速览
  13. 缓存冲突:SWR vs. TanStack Query for React
  14. eclipse切断_切断电源后在哪里传送天气频道
  15. python split()函数
  16. java中的接口是什么?
  17. JEPF快速发开平台
  18. 教你如何用FVD Downloader下载在线视频
  19. 对指针变量取地址意义
  20. codeblocks shotcut

热门文章

  1. IOS多线程使用GCD与信号量实现生产者与消费者模式
  2. php防止恶意刷新与刷票的方法
  3. web前端需要学MySQL吗_web前端需要学什么?容易学吗?
  4. 方式SingleTask 启动Intent设置 不能如愿打开需要的Activity
  5. Harbor容器安装以及相关特性部署与使用(SSL证书+AD域)
  6. 微信小程序 - 屏幕适配
  7. Python学习之列表--自动超市购物车
  8. Halcon 3D moments_object_model_3d简介
  9. mybatis从入门到精通(刘增辉著)-读书笔记第五章
  10. zabbix邮件报警和微信报警