你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。

在 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 不会触发回调。

注意,深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

好了,分享结束,谢谢点赞,下期再见。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部