你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。
在 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 不会触发回调。
注意,深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。
好了,分享结束,谢谢点赞,下期再见。