Vue 中 computed 和 watch 的区别
面试速答(30 秒版 TL;DR)
- computed:用于“派生状态”(由其他响应式数据计算得到),有缓存,依赖不变就不重复计算。
- watch:用于“副作用”(请求、埋点、手动操作 DOM、写入 storage),监听变化后执行回调。
- 一句话:能用 computed 就别用 watch 去算值;需要副作用才用 watch。
computed:派生状态 + 缓存
import { computed, ref } from 'vue';
const price = ref(100);
const count = ref(2);
const total = computed(() => price.value * count.value);
特点:
total会缓存上一次的结果,只有依赖(price/count)变化才重新计算。- 更符合“声明式 UI”:模板用
total,不关心它怎么来的。
watch:监听变化做副作用
import { ref, watch } from 'vue';
const keyword = ref('');
watch(keyword, async (newVal, oldVal) => {
if (!newVal) return;
// 例如:发请求
});
常用配置(Vue 3):
immediate: true:一上来就执行一次deep: true:深度监听对象(代价更高)flush: 'post' | 'pre' | 'sync':控制回调在更新周期中的时机
常见追问
Q1:watchEffect 和 watch 的区别?
watch:显式指定依赖源,回调有新旧值。watchEffect:自动收集依赖,适合“依赖源不固定或很多”的副作用,但不直接给 oldValue。
Q2:能不能用 watch 去实现 computed?
能但不推荐。watch 更像“命令式同步”,容易漏依赖、产生竞态;computed 是“声明式派生”,更稳定可维护。