面试题:Vue 3 中的 watch 和 watchEffect 有什么区别?如何选择使用它们?

在 Vue 3 中,watchwatchEffect 都是用于监听响应式数据变化的 API,但它们的用途和行为有所不同。理解它们的区别并正确选择使用场景,可以帮助你更高效地编写代码。


1. watch 的特点

watch 用于监听特定的响应式数据,并在数据变化时执行回调函数。它的特点包括:

  • 明确监听的目标:需要显式指定要监听的数据源。
  • 惰性执行:默认情况下,回调函数不会立即执行,只有在监听的数据变化时才会执行。
  • 新旧值对比:回调函数会接收新值和旧值作为参数。
  • 更细粒度的控制:支持监听多个数据源,并可以配置 deepimmediate 等选项。

示例:

import { ref, watch } from 'vue';

const count = ref(0);

watch(count, (newValue, oldValue) => {
  console.log(`count 变化: 从 ${oldValue} 变为 ${newValue}`);
});

count.value++; // 输出: count 变化: 从 0 变为 1

2. watchEffect 的特点

watchEffect 用于自动追踪回调函数中使用的响应式数据,并在数据变化时重新执行回调函数。它的特点包括:

  • 自动追踪依赖:不需要显式指定监听的数据源,回调函数中使用的响应式数据会被自动追踪。
  • 立即执行:回调函数会立即执行一次,然后在依赖的数据变化时重新执行。
  • 无新旧值对比:回调函数不会接收新值和旧值作为参数。
  • 适合副作用场景:常用于执行副作用操作(如 DOM 操作、异步请求等)。

示例:

import { ref, watchEffect } from 'vue';

const count = ref(0);

watchEffect(() => {
  console.log(`count 的值是: ${count.value}`);
});

count.value++; // 输出: count 的值是: 1

3. watchwatchEffect 的区别

特性watchwatchEffect
监听目标需要显式指定监听的数据源自动追踪回调函数中的响应式数据
执行时机默认惰性执行(可配置 immediate立即执行,并在依赖变化时重新执行
新旧值对比提供新值和旧值不提供新值和旧值
适用场景需要精确控制监听的数据源和回调逻辑适合副作用操作,自动追踪依赖
配置选项支持 deepimmediate 等选项无额外配置选项

4. 如何选择使用 watchwatchEffect

(1)使用 watch 的场景

  • 需要监听特定的响应式数据。
  • 需要对比新值和旧值。
  • 需要控制回调函数的执行时机(如配置 immediatedeep)。
  • 需要监听多个数据源。

示例:

const state = reactive({ count: 0, name: 'Alice' });

watch(
  () => state.count,
  (newValue, oldValue) => {
    console.log(`count 变化: 从 ${oldValue} 变为 ${newValue}`);
  }
);

watch(
  [() => state.count, () => state.name],
  ([newCount, newName], [oldCount, oldName]) => {
    console.log(`count 或 name 变化`);
  }
);

(2)使用 watchEffect 的场景

  • 需要自动追踪回调函数中的响应式数据。
  • 需要立即执行回调函数(如初始化时执行副作用操作)。
  • 不需要对比新值和旧值。

示例:

const count = ref(0);

watchEffect(() => {
  document.title = `Count: ${count.value}`;
});

count.value++; // 自动更新页面标题

5. 注意事项

  • 性能开销watchEffect 会自动追踪所有依赖,如果依赖过多可能会导致性能问题。
  • 清理副作用watchEffect 的回调函数可以返回一个清理函数,用于在重新执行回调前清理上一次的副作用。
watchEffect((onCleanup) => {
  const timer = setTimeout(() => {
    console.log('执行操作');
  }, 1000);

  onCleanup(() => {
    clearTimeout(timer); // 清理副作用
  });
});

总结

  • watch:适合需要精确控制监听目标和回调逻辑的场景,支持新旧值对比和配置选项。
  • watchEffect:适合自动追踪依赖并执行副作用操作的场景,立即执行且无需显式指定监听目标。

根据具体需求选择合适的 API,可以更高效地实现响应式数据监听和副作用管理。

THE END
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容