简述Vue 3中的watch和watchEffect有何不同?

vue3   2025-03-30 12:10   37   0  

在 Vue 3 中,watch 和 watchEffect 都是用于观察响应式数据变化并执行副作用的 API,但它们在用法和设计目的上有明显区别:

1. 依赖收集方式

  • **watch**
    需要显式指定监听的数据源(通过第一个参数传入),可以是响应式对象、ref 或计算属性。
    示例:

    javascript复制watch(count, (newVal, oldVal) => { /* ... */ })

    或监听多个数据源:

    javascript复制watch([count, name], ([newCount, newName], [oldCount, oldName]) => { /* ... */ })
  • **watchEffect**
    自动收集依赖:在回调函数中用到的响应式数据会被自动追踪。无需手动声明依赖。
    示例:

    javascript复制watchEffect(() => {  console.log(count.value + name.value); // 自动追踪 count 和 name});

2. 执行时机

  • **watch**
    默认惰性执行:首次创建时不会立即运行回调,除非设置 immediate: true
    示例:

    javascript复制watch(count, callback, { immediate: true }); // 立即执行一次
  • **watchEffect**
    立即执行:创建时会立即运行一次回调,用于收集依赖。适合需要初始化的副作用。

3. 回调参数

  • **watch**
    提供变化前后的值newValue 和 oldValue):

    javascript复制watch(count, (newVal, oldVal) => { /* ... */ });
  • **watchEffect**
    没有新旧值参数:回调函数中直接访问当前值,适用于不需要旧值的场景。

    javascript复制watchEffect(() => {  console.log(count.value); // 只获取当前值});

4. 适用场景

  • **watch**

    • 需要精确控制监听的数据源。

    • 需要获取旧值或比较新旧值。

    • 需要惰性执行(如仅在数据变化时触发)。

  • **watchEffect**

    • 依赖多个数据源,且逻辑简单(自动收集依赖)。

    • 需要立即执行副作用(如初始化请求)。

    • 逻辑与依赖关系高度耦合,无需手动维护依赖列表。

5. 停止监听

两者都返回一个 **stop 函数**,调用即可停止监听:

javascript复制const stopWatch = watch(/* ... */);const stopEffect = watchEffect(/* ... */);stopWatch(); // 停止 watchstopEffect(); // 停止 watchEffect

总结对比表

特性watchwatchEffect
依赖声明显式指定自动收集
首次执行默认惰性(需 immediate: true立即执行
新旧值提供不提供
多数据源监听支持数组形式自动收集多个依赖
适用场景精确控制依赖、需要旧值简单副作用、依赖自动追踪

根据需求选择:需要细粒度控制时用 watch,简化代码逻辑时用 watchEffect

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。