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

2024-08-04 11:19:01 220
在 Vue 3 中,`watch` 和 `watchEffect` 是两个用于响应式数据的监视工具,它们各有不同的用法和适用场景。理解它们之间的区别有助于在开发过程中选择合适的工具。

watch

watch 用于监视一个或多个特定的响应式数据源,并在数据变化时执行回调。它类似于 Vue 2 中的 watch 选项,但在 Vue 3 中可以直接在组合式 API 中使用。

基本用法

import { ref, watch } from 'vue';

const count = ref(0);

watch(count, (newVal, oldVal) => {
  console.log(`Count changed from ${oldVal} to ${newVal}`);
});

count.value++; // 输出: Count changed from 0 to 1

特点

  • 精确控制:可以精确地指定要监视的响应式数据。
  • 访问旧值和新值:回调函数可以访问被监视数据的旧值和新值。
  • 惰性执行:只有当被监视的响应式数据发生变化时,回调才会执行。

使用场景

  • 需要监视特定响应式数据的变化。
  • 需要访问旧值和新值来进行比较或其他操作。
  • 需要在数据变化时执行副作用,如 API 调用、数据处理等。

watchEffect

watchEffect 用于立即运行一个函数并在其依赖的响应式数据发生变化时重新运行。它更类似于计算属性,但用于处理具有副作用的逻辑。

基本用法

import { ref, watchEffect } from 'vue';

const count = ref(0);

watchEffect(() => {
  console.log(`Count is: ${count.value}`);
});

count.value++; // 输出: Count is: 1

特点

  • 自动依赖收集:不需要显式指定依赖项,watchEffect 会自动跟踪响应式数据的依赖。
  • 立即执行:在创建时立即执行一次,然后在依赖项变化时重新执行。
  • 简单方便:对于简单的副作用逻辑,非常方便且代码量少。

使用场景

  • 需要在依赖的响应式数据变化时自动重新执行逻辑。
  • 逻辑简单且不需要访问旧值和新值。
  • 需要立即执行一次副作用。

如何选择

选择 watch 还是 watchEffect,取决于具体的使用场景和需求。

使用 watch 的场景

  • 需要精确监视特定响应式数据的变化。
  • 需要访问被监视数据的旧值和新值。
  • 逻辑较复杂,需要对依赖项进行更细粒度的控制。

使用 watchEffect 的场景

  • 逻辑简单,不需要访问旧值和新值。
  • 需要立即执行一次副作用并在依赖项变化时重新执行。
  • 需要自动依赖收集,减少手动指定依赖项的工作。

例子对比

使用 watch

import { ref, watch } from 'vue';

const count = ref(0);
const doubled = ref(0);

watch(count, (newVal, oldVal) => {
  doubled.value = newVal * 2;
  console.log(`Count changed from ${oldVal} to ${newVal}, doubled is now ${doubled.value}`);
});

使用 watchEffect

import { ref, watchEffect } from 'vue';

const count = ref(0);
const doubled = ref(0);

watchEffect(() => {
  doubled.value = count.value * 2;
  console.log(`Count is: ${count.value}, doubled is now ${doubled.value}`);
});

在这个简单的示例中,watchEffect 更简洁,但在更复杂的场景下,watch 可能更适合。

总结

  • watch:适合需要精确控制依赖、访问旧值和新值的场景。
  • watchEffect:适合简单的副作用逻辑,自动依赖收集和立即执行的场景。

通过理解和选择合适的工具,可以更有效地管理和响应数据变化。