什么是watch
当我们需要根据一个数据的变化来进行一些操作的时候我们需要使用侦听器,它能够在响应式数据发生变化的时候触发提供的回调函数
基础侦听
watch 可以侦听不同的数据源。例如:
- ref
- 计算属性
- 响应式对象
- getter函数
- 多个数据源组层的数据
const x = ref(0)
const y = ref(0)// 单个 ref
watch(x, (newX) => {console.log(`x is ${newX}`)
})// getter 函数
watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})
不能直接侦听响应式对象的属性,应使用如下代码
// 提供一个 getter 函数
watch(() => obj.count,(count) => {console.log(`count is: ${count}`)}
)
深层侦听器
如果直接传入响应式对象,会默认创建深层监听,该回调函数会在所有嵌套的数据是触发。
如果我们想只监听对象中的某个属性发生变化在触发则使用如下代码.
watch(() => state.someObject,() => {// 仅当 state.someObject 变化时触发}
)
如果我们想要显式的声明可以使用watch
的第三个参数{deep:treue}
来转换为强制侦听。
立即执行
有时候我们需要一进入页面就执行侦听器一次,那我们可以使用watch的第三个参数
{immediate:treue}`来立即执行。
watchEffect的使用
- watchEffect 是立即执行一次的,不需要指定
immediate
。 - watch 只会追中明确侦听的数据源,而watchEffect 会自动追中所有能访问到的响应式数据。
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
TIP
watchEffect 仅会在其同步执行期间,才追踪依赖。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被追踪。
回调触发时机
默认情况下,侦听器回调会在父组件更新 (如有) 之后、所属组件的 DOM 更新之前被调用。这意味着如果你尝试在侦听器回调中访问所属组件的 DOM,那么 DOM 将处于更新前的状态。
如果想在侦听器回调中能访问被 Vue 更新之后的所属组件的 DOM,你需要指明 flush: ‘post’ 选项:
watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})
后置刷新的 watchEffect() 也可以使用 watchPostEffect()