侦听数据源类型
- ref(包括计算属性)
- 一个响应式对象(不能直接监听响应式对象的属性值,可以通过getter函数返回该属性)
- 一个getter函数
- 多个数据源组成的数组
深层侦听器
直接给watch()
传入一个响应式对象,就会隐式的创建一个深层侦听器,所有嵌套变更都会触发回调。
const obj = reactive({ count: 0 })
watch(obj, (newValue, oldValue) => {
})
obj.count++
而一个返回响应式对性的getter函数,只有在返回不同对象时,才会触发回调函数。
( { deep: true } 也可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器)
watch(
() => state.someObject,
() => {
// 仅当 state.someObject 被替换时触发
}
// { deep: true } 也可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器:
)
即时回调侦听器
我们希望在创建侦听器时,立即执行一遍回调。(watch
默认是懒执行的:仅当数据源变化时,才会执行回调。)
watch(
source,
(newValue, oldValue) => {
// 立即执行,且当 `source` 改变时再次执行
},
{ immediate: true }
)
一次性侦听器(3.4+)
声明周期内,数据源变更只回调一次。
watch(
source,
(newValue, oldValue) => {
// 当 `source` 变化时,仅触发一次
},
{ once: true }
)
watchEffect()
- 可以直接根据回调内的响应式数据产生依赖。不需要显示设置数据源。
- 默认立即回调,不需要指定
immediate: true
。 - 适合有多个依赖项时使用。或者只需要监听一个嵌套数据结构中的几个属性,它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
- watchEffect 仅会在其同步执行期间,才追踪依赖。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被追踪。
watchEffect(async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
})
回调的触发时机
- 默认情况下侦听器回调会在父组件更新之后,所属组件DOM更新之前被调用。
- 如果想在侦听器回调中能访问被 Vue 更新之后的所属组件的 DOM:
- 使用
watchPostEffect
watchEffect
设置flush: 'post'
配置项watch
设置flush: 'post'
配置项
- 使用
- Vue 进行任何更新之前触发触发回调:
- 使用
watchSyncEffect
watchEffect
设置flush: 'sync'
配置项watch
设置flush: 'sync'
配置项
- 使用
停止侦听器
在setup()和script setup中同步语句的侦听器,会在宿主组件卸载时停止自动停止。(异步创建则不会,必须手动停止,比如定时器中创建侦听器)
创建侦听器的返回值是一个函数,调用这个函数即停止对应侦听器。