watch()简介:
-
侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数
-
watch()
默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数 -
watch()
一共有三个参数-
第一个参数:侦听器的源,可以为以下几种
- 一个函数,返回一个值
- 一个ref
- 一个响应式对象
- 或者由以上类型的值组成的数组
-
第二个参数:侦听源发生变化时调用的回调函数。这个函数接受三个参数
- 新值
- 旧值
- 用于注册副作用清理的回调函数(可选,可忽略)
当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值
-
第三个参数(可选):配置对象,支持以下这些选项
immediate
:在侦听器创建是立即触发回调,第一次调用时旧值是undefined
deep
:如果源是对象,强制使用深度遍历,一遍在深层级变更时触发回调flush
:调整回调函数的刷新时机onTrack / onTrigger
:调用侦听器的依赖
-
简单示例
<script setup lang = "ts">
import { ref, reactive, watch } from 'vue'
const person = reactive({
name: 'zhangsan',
age: 18,
school: {
address: 'jinan'
}
})
const updatePerson = () => {
person.name = 'lisi'
person.school.address = 'beijing'
}
watch(
[() => person.name, () => person.school.address],
(newInfo: string[], oldInfo: string[]) => {
console.log(newInfo) // ['lisi', 'beijing']
console.log(oldInfo) // ['zhangsan', 'jinan']
},
{ deep: false }
)
</script>
<template>
<h3>{{ person.name }}</h3>
<h3>{{ person.school.address }}</h3>
<button @click="updatePerson">修改人员信息</button>
</template>
其它注意事项:
-
尽量不要直接将一个响应式对象传递给
watch()
这样会隐式地创建一个深度侦听器,该响应式对象所有属性发生变化时都会执行回调函数,如果响应式对象中属性非常多那么对于性能的牺牲是巨大的。因此请只在必要时使用这种侦听方式,并且要时刻留意性能,尽量使用上面示例中的侦听方式。 -
回调触发时机:当更新了响应式状态之后,它可能回同时触发
Vue
组件的更新和侦听器的回调默认情况下创建的侦听器回调都会在
Vue
组件更新之前被调用,所以导致在侦听器回调函数中访问的Dom将是在Vue
更新之前的的状态。可以通过设置flush
配置项为post
,使得侦听器回调发生在Vue
更新之后。