在 Vue 3 中,watchEffect 是一个用于监听响应式数据变化的 API。它可以在函数内部自动跟踪数据的依赖,并在依赖变化时重新运行函数。

watchEffect的作用以及各个参数的功能讲解:

watchEffect(effect: (onInvalidate: InvalidateCbRegistrator) => void | (() => void) | Promise<void>, options?: WatchEffectOptions): WatchStopHandle

WatchEffectOptions

    watchEffect 函数接受一个可选的选项对象,用于配置监听行为。以下是 WatchEffectOptions 对象的属性及其功能:

例如,以下代码使用 watchEffect 监听 message 的变化,并在变化时执行回调函数。

import { watchEffect } from 'vue';
watchEffect(() => {
  console.log(`message 变为 ${message}`);
});

下面是一个简单的例子,演示了如何使用 watchEffect 监听响应式数据变化:

<template>
  <div>
    <p>输入框的值为:{{ message }}</p>
    <input v-model="message" />
  </div>
</template>
<script>
import { defineComponent, ref, watchEffect } from 'vue';
export default defineComponent({
  setup() {
    const message = ref('');
    watchEffect(() => {
      console.log(`message 值改变为:${message.value}`);
    });
    return {
      message
    };
  }
});
</script>

在这个例子中,我们使用 ref 函数定义了一个名为 message 的响应式数据,并将其初始化为空字符串。我们使用 watchEffect 函数监听 message 的变化,并在函数内部打印出 message 的值。因为 watchEffect 函数会自动跟踪 message 的依赖,所以当用户在输入框中输入内容时,watchEffect 函数就会重新运行,打印出新的 message 值。

需要注意的是,watchEffect 函数的回调函数不需要显式地指定依赖项,它会自动跟踪回调函数内部使用到的所有响应式数据。因此,当你使用 watchEffect 函数时,不需要再使用 watch 函数或 computed 函数来监听数据变化。但是,如果你需要监听某个特定的响应式数据变化,可以在回调函数中使用该数据,这样 watchEffect 就会自动跟踪它。

watchEffect 函数的返回值是一个用于停止监听的函数。当你调用这个函数时,watchEffect 就会停止监听响应式数据的变化。

以下是一个示例,演示如何使用 watchEffect 函数的返回值停止监听:

<template>
  <div>
    <p>输入框的值为:{{ message }}</p>
    <button @click="stopWatching">停止监听</button>
    <input v-model="message" />
  </div>
</template>
<script>
import { defineComponent, ref, watchEffect } from 'vue';
export default defineComponent({
  setup() {
    const message = ref('');
    const stopWatching = watchEffect(() => {
      console.log(`message 值改变为:${message.value}`);
    });
    function stopWatching() {
      stopWatching();
    }
    return {
      message,
      stopWatching
    };
  }
});
</script>

在这个例子中,我们定义了一个名为 stopWatching 的函数,它调用了 watchEffect 函数的返回值,从而停止了监听。我们在模板中添加了一个按钮,当用户点击它时,就会调用 stopWatching 函数,从而停止监听 message 的变化。

watch的作用以及各个参数的功能讲解:

watch 是 Vue 3 中用于监听响应式数据变化的 API,它能够在响应式数据发生变化时执行回调函数。以下是 watch 函数的参数及其功能:

  1. watch(source: string | Function | Ref, callback: Function, options?: WatchOptions): WatchStopHandle
  1. WatchOptions

watch 函数接受一个可选的选项对象,用于配置监听行为。以下是 WatchOptions 对象的属性及其功能:

import { watch } from 'vue';
watch(
  () => message, // 要监听的响应式数据
  (newValue, oldValue) => {
    console.log(`message 从 ${oldValue} 变为 ${newValue}`);
  },
  {
    immediate: true // 在组件挂载时立即执行回调函数
  }
);

watchEffectwatch 都是 Vue 3 中用于监听响应式数据变化的 API,它们之间的主要区别在于回调函数的类型和依赖项的声明方式。

因为 watchEffect 自动追踪响应式数据的变化,所以它更适合处理简单的数据逻辑。如果需要监听特定的响应式数据或使用更高级的选项,可以使用 watch 函数。使用 watch 函数需要显式声明要监听的响应式数据,这可以使代码更具可读性。此外,watch 函数还支持声明多个要监听的响应式数据,这使得它可以处理更复杂的数据逻辑。

总之,如果你只需要监听一些简单的响应式数据变化,可以使用 watchEffect 函数。如果需要监听特定的响应式数据或使用更高级的选项,可以使用 watch 函数。

以下是一个示例,演示 watchEffectwatch 的差别:

<template>
  <div>
    <p>message1 值为:{{ message1 }}</p>
    <p>message2 值为:{{ message2 }}</p>
    <button @click="increment">增加 message1 和 message2 的值</button>
  </div>
</template>
<script>
import { defineComponent, ref, watchEffect, watch } from 'vue';
export default defineComponent({
  setup() {
    const message1 = ref(0);
    const message2 = ref(0);
    // watchEffect 自动追踪响应式数据的变化
    watchEffect(() => {
      console.log(`message1 值变为 ${message1.value}`);
    });
    // watch 需要显式声明要监听的响应式数据
    watch(message2, (newValue, oldValue) => {
      console.log(`message2 从 ${oldValue} 变为 ${newValue}`);
    });
    function increment() {
      message1.value++;
      message2.value++;
    }
    return {
      message1,
      message2,
      increment
    };
  }
});
</script>

在这个例子中,我们声明了两个响应式数据 message1message2,并分别使用了 watchEffectwatch 监听它们的变化。watchEffect 自动追踪 message1 的变化,并在变化时触发回调函数。而 watch 则需要显式声明要监听的 message2,并在它的变化时触发回调函数。在点击按钮时,我们同时增加了 message1message2 的值,从而触发了相应的回调函数。

watchEffectwatch 的区别在于,watchEffect 监听的是一个函数的副作用,而 watch 监听的是一个具体的响应式数据,因此 watchEffect 不需要显式指定监听的数据,它会自动检测 effect 函数中使用的响应式数据,并在其发生变化时执行回调函数。此外,watchEffect 也不需要手动停止监听,它会在组件卸载时自动停止监听。但是,watchEffect 不支持监听选项对象中的 immediateonTrackonTrigger 属性。

如果watch的监听对象是数组:

如果 watch 监听的是一个数组,则可以使用 deep 选项来深度监听数组元素的变化。当 deeptrue 时,watch 会递归监听数组中每个元素的变化。

例如,以下代码使用 watch 监听 list 数组的变化,并在变化时执行回调函数。

import { watch } from 'vue';
watch(
  () => list,
  (newList, oldList) => {
    console.log('list 变化了', newList, oldList);
  },
  { deep: true }
);

在上面的代码中,watch 监听的是一个计算属性,计算属性返回 list 数组。由于在监听选项中设置了 deep: true,因此 watch 会深度监听 list 数组,即递归监听数组中每个元素的变化。

注意,当使用 deep 选项监听数组时,如果数组中的元素是对象,则需要确保这些对象是响应式的,否则无法监听它们的变化。如果数组中的元素不是响应式的对象,则无法监听其变化。

发表回复