在 Vue 3 的 Composition API 中,watch 是一个非常强大的工具,用于监听响应式数据的变化并做出相应的处理。本文将通过一段实际代码来深入解析 watch 的行为和使用技巧。
import { reactive, watch } from 'vue'
const state = reactive({
a: 1,
b: 2,
c: 3
})
watch(
() => {
console.log(state.a + state.b)
return state.a + state.b
},
(val) => {
console.log(val * 2)
}
)
setTimeout(() => {
state.a++
//state.b
state.b--
}, 1000)
Vue 的 watch 函数接收三个参数:
{ immediate: true, deep: true }
。a
、b
和 c
。watch
监听 state.a + state.b
的变化,并在变化时打印其两倍值。a
和 b
的值。当组件加载时,watch
的第一个函数会被立即调用:
() => {
console.log(state.a + state.b) // 输出 3
return state.a + state.b
}
此时 a = 1
, b = 2
,所以 a + b = 3
,控制台输出 3
。
由于这是第一次运行,还没有发生任何变化,因此不会触发回调 (val) => console.log(val * 2)
。
1 秒后,执行以下操作:
state.a++ // a = 2
state.b-- // b = 1
此时 a + b = 3
,与之前的值相同。
虽然 a
和 b
都发生了变化,但它们的和没有改变,因此 watch
回调 (val) => console.log(val * 2)
不会被触发。
但是,下面这行代码仍然会执行:
console.log(state.a + state.b) // 输出 3
这是因为每次依赖项发生变化时,getter 函数都会重新执行一次以检查是否有变化。
3
(来自watch
函数体内 console.log
)3
(来自watch
函数体再次执行)
6
,因为 a + b
的值没有改变watch
强制触发?如果你希望即使值不变也触发回调,可以考虑以下方式:
immediate: true
watch(
() => {
console.log(state.a + state.b)
return state.a + state.b
},
(val) => {
console.log(val * 2)
},
{ immediate: true }
)
这样你会看到两次 3
和一次 6
(在 setTimeout
后)。
注意:
deep: true
对基础类型无效,通常用于对象或数组。
watch
常用于以下场景:
知识点 | 内容 |
---|---|
watch 初始执行 |
会执行一次 getter 函数,但不会触发回调 |
触发回调条件 | 必须是返回值发生变化才会触发 |
控制台输出 | 即使不触发回调,getter 函数也会重新执行 |
强制首次触发 | 可使用 { immediate: true } |
Vue 3 的watch
提供了灵活的数据监听机制,但它的行为有时可能会让人困惑。理解它的工作原理,尤其是如何判断“变化”,对于编写高效且可维护的响应式逻辑至关重要。
通过上面的例子,我们不仅掌握了watch
的基本用法,还了解了它的内部机制以及如何控制其行为。希望这篇文章能帮助你更好地理解和使用 Vue 3 的响应式系统!