在 Vue3 中,watch
用于监听响应式数据的变化并执行副作用操作(如异步请求、复杂逻辑等),其设计更灵活且支持组合式 API。以下是核心要点总结:
1. 基本用法
组合式 API 中
需从 vue
导入 watch
:
import { ref, watch } from 'vue';
const count = ref(0);
// 监听单个 ref
watch(count, (newVal, oldVal) => {
console.log(`count变化:${oldVal} → ${newVal}`);
});
选项式 API 中
在 watch
选项中定义:
export default {
data() {
return { count: 0 };
},
watch: {
count(newVal, oldVal) {
console.log(`count变化:${oldVal} → ${newVal}`);
}
}
};
2. 监听不同类型的数据
(1) 监听 ref
直接传入 ref 变量:
const count = ref(0);
watch(count, (newVal, oldVal) => { /* ... */ });
(2) 监听 reactive
对象
需通过函数返回具体属性,或开启 deep
深度监听:
const state = reactive({ user: { name: 'Alice' } });
// 监听单个属性
watch(
() => state.user.name,
(newVal, oldVal) => { /* ... */ }
);
// 深度监听整个对象
watch(
() => state.user,
(newVal, oldVal) => { /* ... */ },
{ deep: true }
);
(3) 监听多个源
使用数组传入多个监听源:
const count = ref(0);
const name = ref('Alice');
watch(
[count, name],
([newCount, newName], [oldCount, oldName]) => {
console.log(`count或name变化了`);
}
);
3. 配置选项
通过第三个参数配置监听行为:
watch(
data,
callback,
{
deep: true, // 深度监听对象内部变化
immediate: true,// 立即触发一次回调
flush: 'post' // 回调在DOM更新后执行(默认 'pre')
}
);
4. watch
vs watchEffect
特性 | watch | watchEffect |
---|---|---|
依赖收集方式 | 显式指定监听源 | 自动追踪回调中的响应式依赖 |
初始执行 | 需配置 immediate: true | 立即执行一次 |
适用场景 | 精确控制监听目标 | 依赖动态变化或简单副作用 |
示例:watchEffect
自动依赖追踪
const count = ref(0);
watchEffect(() => {
console.log(`count值:${count.value}`);
});
5. 停止监听
通过 watch
返回的停止函数手动取消监听:
const stop = watch(count, (newVal) => { /* ... */ });
// 调用停止函数
stop();
6. 注意事项
-
避免副作用循环
不要在回调中直接修改被监听的数据,否则可能触发无限循环。watch(count, (newVal) => { count.value = newVal + 1; // 错误!导致循环更新 });
-
异步操作处理
若回调中包含异步逻辑,需自行处理竞态条件(如取消未完成的请求)。 -
性能优化
- 避免过度使用
deep: true
(深度监听消耗较大)。 - 对复杂对象优先监听具体属性而非整个对象。
- 避免过度使用
7. 常见场景
-
表单验证:监听输入框变化实时校验
const inputValue = ref(''); watch(inputValue, (newVal) => { if (!isValid(newVal)) showError(); });
-
路由参数监听:响应路由变化加载数据
import { useRoute } from 'vue-router'; const route = useRoute(); watch( () => route.params.id, (newId) => { fetchData(newId); } );
-
依赖异步数据更新:数据加载后执行操作
const data = ref(null); watch(data, (newData) => { if (newData) renderChart(); });
总结
Vue3 的 watch
提供了细粒度的数据监听能力,适用于需要响应数据变化执行异步或复杂逻辑的场景。优先使用 watchEffect
简化代码,但需明确依赖时选择 watch
。合理使用 deep
和 immediate
选项,避免性能问题。