Vue 3 watch 详解:响应式数据监听的最佳实践(六)

在 Vue 3 中,watch 是一个非常强大的工具,用于监听响应式属性的变化并执行特定的操作。通过 watch,你可以在数据发生变化时做出相应的响应,执行自定义的逻辑。本文将详细介绍 watch 的各种用法和最佳实践,帮助你更好地理解和使用这一功能。

什么是 watch?

watch 是 Vue 3 提供的一种响应式数据监听机制。它可以监听单个或多个属性的变化,并在属性发生变化时触发回调函数。watch 使得在响应式属性变化时能够有更多的控制权和灵活性,让你的组件能够更好地响应数据的变化并执行相应的逻辑。

基本用法

在 Vue 3 中,watch 函数用于监听响应式属性。当监听的属性值发生变化时,Vue 会触发回调函数执行。下面是一个简单的示例,展示了如何使用 watch 监听一个计数器的变化:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

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

    return {
      state
    };
  }
};

在这个示例中,每当 state.count 发生变化时,回调函数会被触发,并打印出新旧值。

监听多个响应式属性

如果你想同时监听多个响应式属性,可以通过一个数组来传递监听的多个属性。下面是一个示例,展示了如何同时监听 count 和 name 的变化:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      name: 'Vue3'
    });

    watch([() => state.count, () => state.name], ([newCount, newName], [oldCount, oldName]) => {
      console.log(`count changed from ${oldCount} to ${newCount}`);
      console.log(`name changed from ${oldName} to ${newName}`);
    });

    return {
      state
    };
  }
};

在这个示例中,当 state.count 或 state.name 发生变化时,回调函数会被触发,并打印出新旧值。

深度监听

如果你要监听的是一个对象或数组,并希望对其内部的嵌套属性进行监听,可以使用 deep: true 选项。这会监听对象的所有属性变化。下面是一个示例,展示了如何启用深度监听:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      user: {
        name: 'Alice',
        age: 25
      }
    });

    watch(() => state.user, (newVal, oldVal) => {
      console.log('User object changed:', newVal, oldVal);
    }, { deep: true });

    return {
      state
    };
  }
};

在这个示例中,当 state.user 对象的任何属性发生变化时,回调函数会被触发,并打印出新旧值。

立即执行

默认情况下,watch 只会在监听的值发生变化时触发回调。如果你希望在组件加载时就立即执行一次回调,可以设置 immediate: true。下面是一个示例,展示了如何启用立即执行:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

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

    return {
      state
    };
  }
};

在这个示例中,当组件加载时,回调函数会立即执行一次,并打印出初始值。

异步操作

如果你在 watch 中需要执行异步操作,可以直接在回调函数中使用 async 和 await,这可以让你处理诸如 API 请求、数据存储等操作。下面是一个示例,展示了如何在 watch 中执行异步操作:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

    watch(() => state.count, async (newVal, oldVal) => {
      console.log(`count changed from ${oldVal} to ${newVal}`);
      // 假设执行一个异步请求
      await fetch(`https://api.example.com/count/${newVal}`);
    });

    return {
      state
    };
  }
};

在这个示例中,当 state.count 发生变化时,会触发一个异步请求。

监听多个属性并使用 handler 函数

你还可以将 watch 用作监听多个属性的处理程序。下面是一个示例,展示了如何使用 handler 函数:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      name: 'Vue3'
    });

    const handler = ([newCount, newName], [oldCount, oldName]) => {
      console.log(`count changed: ${oldCount} → ${newCount}`);
      console.log(`name changed: ${oldName} → ${newName}`);
    };

    watch([() => state.count, () => state.name], handler);

    return {
      state
    };
  }
};

在这个示例中,当 state.count 或 state.name 发生变化时,handler 函数会被触发,并打印出新旧值。

watchEffect 简化版的监听

Vue 3 还提供了 watchEffect API,它比 watch 更加简洁,可以自动地跟踪响应式数据的变化,而不需要指定具体的数据源。下面是一个示例,展示了如何使用 watchEffect:

import { reactive, watchEffect } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

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

    return {
      state
    };
  }
};

在这个示例中,watchEffect 会自动检测到 state.count 的变化并在变化时触发回调。

flush 选项

flush 选项用于控制 watch 的回调执行时机。默认情况下,watch 回调会在 DOM 更新后执行。如果你需要在更新之前执行回调,可以使用 flush: 'pre'。下面是一个示例,展示了如何使用 flush 选项:

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

    watch(() => state.count, (newVal, oldVal) => {
      console.log(`count changed from ${oldVal} to ${newVal}`);
    }, { flush: 'pre' });

    return {
      state
    };
  }
};

在这个示例中,当 state.count 发生变化时,回调函数会在 DOM 更新之前执行。

总结

watch 是 Vue 3 中一个非常强大的工具,用于监听响应式属性的变化并执行特定的操作。通过本文的介绍,你应该已经掌握了 watch 的基本用法、监听多个属性、深度监听、立即执行、异步操作、使用 handler 函数以及 watchEffect 的使用方法。希望这些知识能帮助你在开发中更好地利用 watch,提升应用的响应性和灵活性。

如果你有任何问题或建议,欢迎在评论区留言。祝你编码愉快!