[Vue] computed、watch 和 watchEffect 的区别
前言
当依赖的数据发生改变,computed
、watch
和 watchEffect
都会被触发。但是它们之间又有自己的特点,使用场景也不一样。
关于 computed 是什么,以及它和普通函数的区别、运用场景,查看我的另一篇博文:[Vue] computed 和 普通函数的区别。
特性 | watch |
watchEffect |
computed |
---|---|---|---|
用途 | 监听特定响应式数据的变化,并在变化时执行回调 | 自动追踪所有响应式数据并执行副作用 | 定义基于响应式数据的计算属性 |
依赖声明 | 显式声明要监听的数据或计算属性 | 自动追踪回调中读取的所有响应式数据 | 显式声明依赖的响应式数据 |
返回值 | 无,主要用于执行副作用 | 无,主要用于执行副作用 | 返回计算得到的值 |
缓存 | 不缓存结果,每次依赖变化时都会触发 | 不缓存结果,每次依赖变化时都会触发 | 缓存计算结果,只有依赖变化时重新计算 |
初始执行 | 不会立即执行,只有当依赖变化时才执行 | 初始时立即执行一次,然后每次依赖变化时重新执行 | 在被读取时惰性求值 |
旧值与新值 | 可以访问旧值和新值 | 不提供旧值和新值 | 不提供旧值和新值 |
深度监听 | 可以通过 { deep: true } 选项进行深度监听 |
不支持深度监听 | 不支持深度监听 |
适用场景 | 需要精确控制响应式数据的监听和副作用 | 需要自动追踪多个依赖的副作用 | 计算属性需要在模板中展示,或计算结果需缓存 |
watch
用途:watch
是显式的监听器,主要用于监听特定的响应式数据变化。你可以选择要监听哪些变量(或计算属性),并在它们发生变化时执行特定的逻辑。
场景:适合需要在某些数据变化时执行异步操作或复杂逻辑的场景,比如发起 API 请求、手动计算等。
const stop = watch(count, (newValue, oldValue) => {
console.log(`count 从 ${oldValue} 变为 ${newValue}`);
});
// 停止监听
stop();
watchEffect
用途:watchEffect 是更自动化的反应式追踪器,能够自动追踪在回调函数中使用的所有响应式数据,并在这些数据发生变化时重新执行回调函数。
场景:适合依赖于多个响应式数据的场景,尤其是在你不想手动指定要监听的依赖时。常用于简化对多个响应式状态的追踪。
const stop = watchEffect(async (onCleanup) => {
const { response, cancel } = doAsyncWork(id.value)
// `cancel` 会在 `id` 更改时调用
// 以便取消之前
// 未完成的请求
onCleanup(cancel)
data.value = await response
});
// 停止监听
stop();