Vue 3 Watch API 比较
以下表格总结了Vue 3中watch相关API的区别和联系:
基础API比较
| 特性/API | watch | watchEffect |
|---|
| 基本形式 | watch(source, callback, options?) | watchEffect(effect, options?) |
| 执行时机 | 懒执行,仅当源数据变化时触发回调 | 立即执行,然后在依赖变化时重新执行 |
| 回调函数参数 | 提供newValue和oldValue参数 | 不提供参数,需要在副作用函数内处理状态 |
| 依赖追踪 | 明确指定监听源 | 自动追踪副作用函数内的响应式依赖 |
| 清理机制 | 通过回调函数的onCleanup参数 | 通过effect函数的参数 |
| 返回值 | 返回停止监听的函数句柄 | 返回停止监听的函数句柄 |
| 适用场景 | 需要比较新旧值或只在特定状态变化时执行副作用 | 需要自动追踪依赖并响应变化,更关注副作用执行 |
选项参数比较
| 选项 | watch | watchEffect |
|---|
| immediate | 支持,决定是否立即执行回调 | 不适用(始终立即执行) |
| deep | 支持,深度监听对象变化 | 不适用(通过依赖追踪自动处理) |
| once | 支持(Vue 3.4+),只触发一次 | 不支持 |
| scheduler | 支持,自定义调度器 | 支持,自定义调度器 |
| onTrack/onTrigger | 支持,调试依赖追踪 | 支持,调试依赖追踪 |
watch API 变体
| API | 描述 | 特点 |
|---|
| watch | 基础watch API | 最灵活,支持多种源和选项 |
| watchEffect | 简化的watch API | 自动追踪依赖,语法简洁 |
| watchPostEffect | 同步在组件更新后触发 | 在DOM更新后执行,类似updated生命周期 |
| watchSyncEffect | 同步触发 | 与状态变更同步执行,不异步 |
使用示例对比
watch 示例
const count = ref(0)
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${oldValue} to ${newValue}`)
})
watch(
() => state.someNestedValue,
(newValue, oldValue) => {
},
{ deep: true, immediate: true }
)
watchEffect 示例
watchEffect(() => {
console.log(`count is: ${count.value}`)
})
watchEffect((onCleanup) => {
const timer = setTimeout(() => {
}, 1000)
onCleanup(() => {
clearTimeout(timer)
})
})
选择建议
使用 watch 当:
- 需要访问变化前后的值
- 只在特定状态变化时执行副作用
- 需要懒执行副作用(不立即执行)
- 需要精确控制监听的源
使用 watchEffect 当:
- 需要自动追踪多个依赖
- 更关注副作用的执行而非具体值的变化
- 需要立即执行副作用
- 副作用涉及多个响应式属性
性能考虑
| 方面 | watch | watchEffect |
|---|
| 依赖追踪开销 | 只追踪明确指定的源 | 需要分析副作用函数以追踪依赖 |
| 精确性 | 更精确,只监听指定源 | 可能追踪到非必要依赖 |
| 内存占用 | 通常更少 | 可能因追踪更多依赖而占用更多内存 |