Vue 3 Watch API 比较

53 阅读2分钟

Vue 3 Watch API 比较

以下表格总结了Vue 3中watch相关API的区别和联系:

基础API比较

特性/APIwatchwatchEffect
基本形式watch(source, callback, options?)watchEffect(effect, options?)
执行时机懒执行,仅当源数据变化时触发回调立即执行,然后在依赖变化时重新执行
回调函数参数提供newValue和oldValue参数不提供参数,需要在副作用函数内处理状态
依赖追踪明确指定监听源自动追踪副作用函数内的响应式依赖
清理机制通过回调函数的onCleanup参数通过effect函数的参数
返回值返回停止监听的函数句柄返回停止监听的函数句柄
适用场景需要比较新旧值或只在特定状态变化时执行副作用需要自动追踪依赖并响应变化,更关注副作用执行

选项参数比较

选项watchwatchEffect
immediate支持,决定是否立即执行回调不适用(始终立即执行)
deep支持,深度监听对象变化不适用(通过依赖追踪自动处理)
once支持(Vue 3.4+),只触发一次不支持
scheduler支持,自定义调度器支持,自定义调度器
onTrack/onTrigger支持,调试依赖追踪支持,调试依赖追踪

watch API 变体

API描述特点
watch基础watch API最灵活,支持多种源和选项
watchEffect简化的watch API自动追踪依赖,语法简洁
watchPostEffect同步在组件更新后触发在DOM更新后执行,类似updated生命周期
watchSyncEffect同步触发与状态变更同步执行,不异步

使用示例对比

watch 示例

// 监听单个ref
const count = ref(0)
watch(count, (newValue, oldValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`)
})

// 监听getter函数
watch(
  () => state.someNestedValue,
  (newValue, oldValue) => {
    // 处理变化
  },
  { deep: true, immediate: true }
)

watchEffect 示例

// 自动追踪依赖
watchEffect(() => {
  console.log(`count is: ${count.value}`)
  // 自动追踪count.value作为依赖
})

// 清理副作用
watchEffect((onCleanup) => {
  const timer = setTimeout(() => {
    // 一些异步操作
  }, 1000)
  
  onCleanup(() => {
    clearTimeout(timer)
  })
})

选择建议

使用 watch 当:

  1. 需要访问变化前后的值
  2. 只在特定状态变化时执行副作用
  3. 需要懒执行副作用(不立即执行)
  4. 需要精确控制监听的源

使用 watchEffect 当:

  1. 需要自动追踪多个依赖
  2. 更关注副作用的执行而非具体值的变化
  3. 需要立即执行副作用
  4. 副作用涉及多个响应式属性

性能考虑

方面watchwatchEffect
依赖追踪开销只追踪明确指定的源需要分析副作用函数以追踪依赖
精确性更精确,只监听指定源可能追踪到非必要依赖
内存占用通常更少可能因追踪更多依赖而占用更多内存