曾经以为自己会用 watch
、 watchEffect
了,后来发现只是略懂皮毛。最近我就把 Vue3 的侦听器全面梳理了一下,分享给大家。看看有没有你不会的吧,一起学起来!
Watch
基本用法
当我们需要在数据变化时执行一些“副作用”:如更改 DOM、执行异步操作,我们可以使用 watch
函数:
<script setup>
import { ref, watch } from 'vue'
const question = ref('')
const answer = ref('This is answer. ;-)')
// 侦听一个 ref
watch(question, async (newQuestion, oldQuestion) => {
answer.value = 'Thinking...'
const res = await fetch('https://...')
answer.value = (await res.json()).answer
})
</script>
<template>
<input v-model="question" />
<p>{
{ answer }}</p>
</template>
watch()
一共可以接受三个参数,侦听数据源、回调函数和配置选项。
侦听数据源
watch
的第一个参数可以是不同形式的“数据源”,它可以是:
- 一个 ref
- 一个计算属性
- 一个 getter 函数(有返回值的函数)
- 一个响应式对象
- 以上类型的值组成的数组
const x = ref(1)
const y = ref(1)
const doubleX = computed(() => x.value * 2)
const obj = reactive({ count: 0 })
// 单个 ref
watch(x, (newValue) => {
console.log(`x is ${newValue}`)
})
// 计算属性
watch(doubleX, (newValue) => {
console.log(`doubleX is ${newValue}`)
})
// getter 函数
watch(
() => x.value + y.value,
(sum) => {
console.log(`sum of x + y is: ${sum}`)
}
)
// 响应式对象
watch(obj, (newValue, oldValue) => {
// 在嵌套的属性变更时触发
// 注意:`newValue` 此处和 `oldValue` 是相等的
// 因为它们是同一个对象!
})
// 以上类型的值组成的数组
watch([x, () => y.value], ([newX, newY]) => {
console.log(`x is ${newX} and y is ${newY}`)
})
注意,你不能直接侦听响应式对象的属性值,例如:
const obj = reactive({ count: 0 })
// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {
console.log(`count is: ${count}`)
})
这里需要用一个返回该属性的 getter 函数:
// 提供一个 getter