• 作者:老汪软件技巧
  • 发表时间: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>

_watch监听对象值变化_watch监听数据变化原理

注意: 留意第五行代码,要尽量放在最前面,一定不能异步函数中的语句之后调用它。但如果你想不受同步异步约束,可以用以下方法。

不受同步约束的用法

上面的用法容易有容易有异步问题 ,官方其实有提供更简洁并且能兼顾异步的用法。

如下所示,把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比较常用而且也确实有这种应用场景的缺陷,所以写这篇文章分享一下。

如果有哪里写的不对或者有更好建议欢迎大佬指点。