- 作者:老汪软件技巧
- 发表时间:2024-09-05 10:02
- 浏览量:
前言
Vue3.5新增内容我都一个个看了一圈,除了props优化比较值得细看外,还有onWatcherCleanup这个用于对watch监听的副作用清理的API目前Vue英文文档更新了对应内容。
本文主要细说onWatcherCleanup副作用清理API所带来的作用和具体用法。
什么场景需要副作用清理?
作为一名用Vue开发的程序员,watch算是必不可少的,但Vue3.5之前其实有缺陷的,特别是处理异步时。
如下所示,有时候我们会在watch中进行接口请求之类的异步操作,但如果userId在请求完成之前发生了更改怎么办?这时会使用已经过期的userId进行接口请求,因为接口请求已经在进行中,从而导致异常。
<script setup>
import { watch, onWatcherCleanup } from 'vue';
watch(id, (userId) => {
fetch(`/api/user/${userId}`).then(() => {
})
})
script>
用onWatcherCleanup进行副作用清理
作用简述: onWatcherCleanup就是专门用来解决上述例子或者相似的业务场景,即在userId更改为新值时取消过时的请求。如下所示
<script setup>
import { watch, onWatcherCleanup } from 'vue'
watch(id, (userId) => {
const contr = new AbortController()
fetch(`/api/user/${userId}`, { signal: contr.signal }).then(() => {
})
onWatcherCleanup(() => {
contr.abort()
})
})
script>
注意: 留意第五行代码,要尽量放在最前面,一定不能异步函数中的语句之后调用它。但如果你想不受同步异步约束,可以用以下方法。
不受同步约束的用法
上面的用法容易有容易有异步问题 ,官方其实有提供更简洁并且能兼顾异步的用法。
如下所示,把onCleanup函数作为第三个参数传递回调,如下所示
<script setup>
import { watch } from 'vue'
watch(id, (newId, oldId, onCleanup) => {
onCleanup(() => {
// 清理器
})
})
script>
但如果使用watchEffect时单独传入一个onCleanup即可,如下所示
<script setup>
import { watchEffect } from 'vue'
watchEffect((onCleanup) => {
onCleanup(() => {
// 清理器
})
})
script>
由于onCleanup通过函数传递的参数与观察者实例绑定在一起,所以它不受同步约束,因此更推荐这种用法。
小结
在这次Vue3.5(2024-09-03)版本小更新中,引入的onWatcherCleanup算是比较实用的了,值得去了解具体用法和应用场景,毕竟watch比较常用而且也确实有这种应用场景的缺陷,所以写这篇文章分享一下。
如果有哪里写的不对或者有更好建议欢迎大佬指点。