Vue3.5+ 侦听器的3个更新
你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。
在 Vue3.5+ 中,对于侦听器的更新有以下几个方面:暂停/恢复侦听器、副作用清理/onWatcherCleanup和deep遍历深度,如果对此熟悉可以直接划走了,如果没有划走就一起看看吧。
暂停/恢复侦听器
在 Vue3.5 之前,watch 和 watchEffect 有一个返回值,为 unwatch,用于停止侦听器,在 Vue3.5+ 中,返回值有所变动,新增了 停止和恢复侦听器的方法。
const { stop, pause, resume } = watch(someRef, () => {})
const { stop, pause, resume } = watchEffect(() => {})
// 暂停侦听器
pause()
// 稍后恢复
resume()
// 停止
stop()
注意,pause 停止侦听器后,可以调用 resume 恢复侦听器,但 stop 是停止侦听器,调用后会清除侦听器,调用 resume 不能恢复!
副作用清理
在 Vue3.5 之前,watch 的第三个参数和 watchEffect 的第一个参数为副作用清理函数,在 3.5+ 中,Vue 提供了一个新方法 onWatcherCleanup,用于清理副作用,使用更方便。
watch
副作用清理:
watch(id, async (newId, oldId, onCleanup) => {
const { response, cancel } = doAsyncWork(newId)
// 当 `id` 变化时,`cancel` 将被调用,
// 取消之前的未完成的请求
onCleanup(cancel)
data.value = await response
})
3.5+ 中的副作用清理:
import { onWatcherCleanup } from 'vue'
watch(id, async (newId) => {
const { response, cancel } = doAsyncWork(newId)
onWatcherCleanup(cancel)
data.value = await response
})
watchEffect
副作用清理:watchEffect(async (onCleanup) => {
const { response, cancel } = doAsyncWork(newId)
// 如果 `id` 变化,则调用 `cancel`,
// 如果之前的请求未完成,则取消该请求
onCleanup(cancel)
data.value = await response
})
3.5+ 中的副作用清理:
import { onWatcherCleanup } from 'vue'
watchEffect(async () => {
const { response, cancel } = doAsyncWork(newId)
// 如果 `id` 变化,则调用 `cancel`,
// 如果之前的请求未完成,则取消该请求
onWatcherCleanup(cancel)
data.value = await response
})
onWatcherCleanup()
注册一个清理函数,在当前侦听器即将重新运行时执行。只能在 watchEffect
作用函数或 watch
回调函数的同步执行期间调用 (即不能在异步函数的 await
语句之后调用)。
示例:
import { watch, onWatcherCleanup } from 'vue'
watch(id, (newId) => {
const { response, cancel } = doAsyncWork(newId)
// 如果 `id` 变化,则调用 `cancel`,
// 如果之前的请求未完成,则取消该请求
onWatcherCleanup(cancel)
})
deep 设置遍历深度
watch 方法的第三个可选的参数是一个对象,支持的选项其中之一是deep,如果源是对象,强制深度遍历,以便在深层级变更时触发回调。
在 Vue 3.5+ 中,deep
选项还可以是一个数字,表示最大遍历深度——即 Vue 应该遍历对象嵌套属性的级数。
<template>
<button @click="handleClick">公共组件-输入框</button>
<p>{{ person }}</p>
</template>
<script setup>
import { ref, watch } from 'vue';
const person = ref({
name: 'zhangsan',
age: 20,
likes: {
color: 'blue',
fruit: 'apple'
}
})
watch(person,
(newValue, oldValue) => {
console.log(newValue, oldValue.value)
},
{ deep: 1 }
)
function handleClick() {
// person.value.name += '~'
// person.value.age++
person.value.likes = {
car: 'BYD'
}
}
</script>
以上示例代码,知会监听 someObject 数据第一层的变化,即修改name、age和替换likes时,watch的回调才会触发,直接修改likes的color或 fruit 不会触发回调。
注意,深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。
好了,分享结束,谢谢点赞,下期再见。