Vue3中的watch和wactEffect有什么区别,分别适用在什么场景?

240 阅读2分钟

在 Vue3 中,watchwatchEffect是用于响应式监听数据变化的两个 API,它们的主要区别和适用场景如下:

核心区别

  1. 触发时机

    • watch:只监听明确指定的数据源,且只有当这些数据源变化时才会触发回调。
    • watchEffect:会自动追踪其内部使用的所有响应式依赖,并在初始执行时立即触发一次,之后依赖变化时再次触发。
  2. 依赖声明方式

    • watch:需要显式指定要监听的数据源,可以是一个或多个响应式引用、计算属性等。
    • watchEffect:不需要显式指定依赖,自动捕获回调函数中使用的所有响应式数据。
  3. 回调参数

    • watch:回调函数接收三个参数:新值、旧值和可选的onCleanup函数(用于清理副作用)。
    • watchEffect:回调函数只接收一个onCleanup函数,不提供新旧值对比。

适用场景

  1. watch 的适用场景

    • 需要访问变化前后的值(例如计算差值、记录变更历史)。
    • 监听特定数据的变化(例如表单输入、路由参数)。
    • 需要延迟或异步执行副作用(例如 API 请求)。
    • 需要在组件销毁时手动清理副作用(例如定时器、WebSocket 连接)。
  2. watchEffect 的适用场景

    • 需要根据多个响应式依赖自动触发副作用(例如自动保存表单数据)。
    • 副作用不需要访问旧值(例如更新 DOM、同步本地存储)。
    • 简化依赖追踪(无需显式列出所有依赖)。

示例对比

以下是一个简单的示例,展示两者的差异:

import { ref, watch, watchEffect } from 'vue'

const count = ref(0)
const double = computed(() => count.value * 2)

// watch示例:监听count变化
watch(count, (newValue, oldValue) => {
  console.log(`count从${oldValue}变为${newValue}`)
  // 可以访问新旧值进行比较
})

// watchEffect示例:自动追踪所有依赖
watchEffect(() => {
  console.log(`count或double变化了:${count.value}, ${double.value}`)
  // 不需要显式声明依赖,只要内部使用的响应式数据变化就会触发
})

// 修改count值
count.value++ // 同时触发watch和watchEffect

总结

  • 使用 watch:当需要精确控制监听的数据源,并需要访问变化前后的值时。
  • 使用 watchEffect:当需要自动响应所有依赖的变化,且不需要新旧值对比时。

最后,以官方文档清晰的说明来结尾:

image.png

选择合适的 API 可以使代码更清晰、更高效,避免不必要的副作用触发。