在 Vue 3 中,watch
和 watchEffect
是两个用于响应式数据侦听和副作用管理的重要 API。它们虽然有相似之处,但在使用场景和功能上有明显的区别。以下是对这两个 API 的详细介绍:
watch
功能
watch
用于侦听响应式数据的变化,并在数据变化时执行指定的回调函数。它适用于需要对数据变化做出响应的场景,如处理异步请求、执行副作用、更新外部状态等。
基本用法
<template>
<div>
<input v-model="count" placeholder="Enter a number" />
<p>Count is: {{ count }}</p>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
// 侦听 count 变量的变化
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});
</script>
参数
- 侦听的目标:可以是响应式数据、计算属性或一个 getter 函数(如果传入 getter 函数,则 watch 会侦听其返回的响应式数据)。
- 回调函数:在侦听的目标数据变化时调用的函数,接受两个参数:
newValue
:数据变化后的新值。oldValue
:数据变化前的旧值。
- 配置对象(可选):
immediate
:如果设置为true
,则在侦听器创建时会立即调用回调函数,而不仅仅在数据变化时调用。deep
:如果设置为true
,则侦听嵌套对象的所有属性变化。flush
:可以设置为'pre'
、'post'
或'sync'
,控制回调函数的执行时机。
高级用法
watch(
[count, anotherValue], // 侦听多个响应式数据
([newCount, newValue], [oldCount, oldValue]) => {
console.log(`Count changed from ${oldCount} to ${newCount}`);
console.log(`AnotherValue changed from ${oldValue} to ${newValue}`);
},
{ immediate: true, deep: true } // 配置选项
);
- 侦听多个数据:可以将一个数组传递给
watch
,这样可以同时侦听多个响应式数据。 - 深度侦听:如果
deep
设置为true
,会侦听对象内部的属性变化。
watchEffect
功能
watchEffect
用于自动追踪它作用域内所有响应式数据的变化,并在数据变化时重新执行指定的副作用函数。它更加简洁,适用于自动化的副作用管理,如更新 DOM、处理简单的依赖关系等。
基本用法
<template>
<div>
<input v-model="count" placeholder="Enter a number" />
<p>Count is: {{ count }}</p>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
const count = ref(0);
// 自动追踪 count 的变化
watchEffect(() => {
console.log(`Count is now: ${count.value}`);
});
</script>
参数
- 副作用函数:一个函数,其中的所有响应式数据都会被自动追踪。当这些数据变化时,副作用函数会重新执行。
高级用法
这两个 API 各有其适用场景,合理选择可以帮助你更高效地管理 Vue 组件中的响应式数据和副作用。
总结
- 自动追踪:
watchEffect
会自动追踪其内部使用的响应式数据。当副作用函数内部的响应式数据变化时,副作用函数会自动重新执行。 - 清理副作用:如果副作用函数返回一个清理函数,则在函数重新执行前会先调用这个清理函数。这对于处理订阅、定时器等资源清理很有用。
watchEffect(() => { console.log(`Count is now: ${count.value}`); // 清理副作用(例如清理定时器) return () => { console.log('Cleaning up...'); }; });
对比
watch
vswatchEffect
-
明确 vs 自动追踪:
watch
需要明确指定要侦听的响应式数据。适合需要精确控制的场景。watchEffect
自动追踪副作用函数内所有响应式数据。适合处理简单副作用,特别是当你希望 Vue 自动处理依赖时。
-
副作用处理:
watch
通常用于处理数据变化时的副作用,特别是复杂逻辑和异步操作。watchEffect
适用于更简单的副作用场景,自动处理副作用的执行。
-
配置选项:
watch
提供了更多的配置选项,如deep
、immediate
、flush
,提供更细粒度的控制。watchEffect
没有这些配置选项,但可以通过返回清理函数来处理副作用的清理。
- 使用
watch
当你需要对特定的响应式数据变化进行处理,特别是需要复杂逻辑或异步操作时。 - 使用
watchEffect
当你需要自动追踪响应式数据,并处理简单的副作用时。