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 让监听逻辑也可以更好封装!

posted @ 2025-04-27 16:33  闲云-野鹤  阅读(247)  评论(0)    收藏  举报