在 Vue 3 中,watch
和 watchEffect
都是用来观察响应式数据变化并执行副作用的函数,但它们之间有一些关键的区别:
watch
-
显式依赖:
watch
需要你明确指定要监听的响应式数据。这意味着你必须列出所有你想要监听的数据源。 -
惰性:
watch
默认是惰性的,也就是说,它的回调函数不会在组件初始化时立即执行,而是在第一次数据变化后才执行。 -
旧值和新值:
watch
的回调函数会接收到变化前后的值,这允许你在回调中访问旧值和新值。 -
停止侦听:
watch
返回一个停止函数,你可以调用它来停止侦听。
import { ref, watch } from 'vue';
const count = ref(0);
// 监听单个数据源
watch(count, (newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
});
// 监听多个数据源
watch([foo, bar], ([newFoo, newBar], [oldFoo, oldBar]) => {
console.log(`foo changed from ${oldFoo} to ${newFoo}`);
console.log(`bar changed from ${oldBar} to ${newBar}`);
});
// 启动侦听器
const stopWatch = watch(count, (newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
});
// 模拟一些操作
count.value = 1; // 输出: count changed from 0 to 1
count.value = 2; // 输出: count changed from 1 to 2
// 停止侦听
stopWatch();
// 此时再改变 count 的值,将不会再有输出
count.value = 3; // 不会有输出
watchEffect
-
隐式依赖:
watchEffect
会自动跟踪其回调函数中使用的响应式数据的依赖关系。当你调用watchEffect
时,它会立即执行一次回调函数,并在回调函数中使用的任何响应式数据发生变化时再次执行。 -
非惰性:
watchEffect
不是惰性的,它在组件初始化时就会立即执行一次,不需要等待数据变化。 -
无旧值和新值:
watchEffect
的回调函数不接收旧值和新值,因为它只关心数据是否发生了变化,而不关心变化前后的具体值。 -
停止侦听:
watchEffect
同样返回一个停止函数,可以用来停止侦听。
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`count is now ${count.value}`);
});
// 当 count 变化时,上面的回调函数会再次执行。
-
如果你需要精确控制哪些数据应该触发侦听器的执行,并且需要访问变化前后的值,那么应该使用
watch
。 -
如果你希望自动跟踪回调函数中的依赖,并且不需要访问旧值和新值,那么可以使用
watchEffect
。
在实际应用中,选择使用 watch
还是 watchEffect
取决于你的具体需求和偏好。两者都是非常有用的工具,可以帮助你处理响应式数据的变化。
评论区