Vue2 vs Vue3 的 watch 差异总结
🎯 Vue2 vs Vue3 的 watch 差异总结
| 对比点 | Vue2 watch | Vue3 watch |
|---|---|---|
| 监听对象/数组 | 默认深度监听(但是不准确) | 默认浅监听,需要手动 deep: true |
| 监听多个数据 | 不支持(要自己写多个 watch) | 支持直接 watch 多个 sources ✅ |
| 回调参数 | (newVal, oldVal) |
(newVal, oldVal, onCleanup) ✅ |
| 取消副作用(比如定时器) | 不方便(要手动写在 data 或 methods) | 有内置 onCleanup,优雅清理 ✅ |
| 初次执行 immediate | 有 immediate: true |
依然有,没区别 |
| 深度监听 deep | 有 deep: true(容易误用) |
同样有,但是使用方式更合理 |
| 监听 computed/函数 | 不方便(需要 workarounds) | 支持传函数,天然兼容 computed ✅ |
| 类型 | 选项式 API(写在 watch: {} 里) | Composition API(直接 watch 调用) ✅ |
🧠 具体讲解(带例子)
1. 监听对象/数组的差异
Vue2 默认是深监听
watch: {
obj: function(newVal, oldVal) {
console.log(newVal);
}
}
问题:
- Vue2是基于
Object.defineProperty - 对新增/删除属性,监听不到!
- 有很多边界问题(比如数组改索引监听不到)
Vue3 默认是浅监听(需要 deep: true)
import { reactive, watch } from 'vue';
const obj = reactive({ a: 1 });
watch(obj, (newVal, oldVal) => {
console.log('changed');
});
- 只会监听 obj 这个整体引用
- 如果要监听里面的
a变化,必须加{ deep: true }
watch(obj, (newVal, oldVal) => {
console.log('changed');
}, { deep: true });
✅ 这样就更清晰、控制更细粒度!
2. 监听多个值
Vue2 不支持,要写多个 watch:
watch: {
a(val) { ... },
b(val) { ... }
}
Vue3 支持直接监听数组!
watch([a, b], ([newA, newB], [oldA, oldB]) => {
console.log(newA, newB);
});
超级方便!尤其是在需要联合监听多个条件时!
3. 副作用清理 onCleanup
Vue3 在 watch 回调里给了一个 onCleanup 参数,可以专门清理副作用,比如定时器、请求等!
watch(source, (newVal, oldVal, onCleanup) => {
const timer = setTimeout(() => {
// do something
}, 1000);
onCleanup(() => {
clearTimeout(timer); // 页面切换、值变化时自动清理
});
});
- 以前 Vue2 要自己手动管理,不好用
- Vue3 自带生命周期,防止内存泄漏
4. 监听计算属性或函数
Vue3 可以直接 watch 一个函数,比如:
const count = ref(0);
watch(() => count.value + 1, (newVal, oldVal) => {
console.log(newVal); // 每次 count 变化,newVal 都是 count+1
});
非常灵活!
而 Vue2 只能写在 computed/watch 里,非常僵硬。
🚀 小结一句话:
- Vue2 watch 粗糙、容易踩坑
- Vue3 watch 更灵活、更安全、更强大
- 组合式 API 让监听逻辑也可以更好封装!

浙公网安备 33010602011771号