在 Vue 3 中,响应式系统允许我们声明性的绑定数据和 DOM,当数据变化时,DOM 也会自动更新。为了实现这一点,Vue 提供了特殊的 API,其中包括 reactive 和 ref,用于分别创建响应式对象和响应式基本类型值。在这些基础之上,我们可以使用 watch 和 watchEffect 来监听数据的变化并执行相应的逻辑。
watch 的使用
watch 是 Vue 3 提供的一种用于监听响应式数据变化的工具。在某些场景下,我们可能需要在特定数据变化时执行一些额外的逻辑,watch就是为此而生的。我们可以使用 watch来监听侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
示例
<template><div>{{ state.count }}</div><button @click="state.count++">点击增加</button></template><script setup>import { reactive, watch } from "vue";const state = reactive({count: 0,});watch(() => state.count,(newValue, oldValue) => {console.log(Count changed from ${oldValue} to ${newValue});});</script>
在这个示例中,我们通过 reactive 创建了一个响应式对象 state,其中包含一个 count属性。随后,我们使用 watch 来监听 state.count 的变化。当 count发生变化时,回调函数会打印出新值和旧值。
watchEffect 的使用
watchEffect 是 Vue 3 中另一个非常有用的 API。与 watch 不同,watchEffect立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。watchEffect 自动追踪依赖,它会在其所依赖的响应式数据变化时自动执行一次,同时也会在组件卸载时自动清理。
示例
<template><div>{{ state.count }}</div><button @click="state.count++">点击增加</button></template><script setup>import { reactive, watchEffect } from "vue";const state = reactive({count: 0,});watchEffect(() => {console.log(Count value is ${state.count});});</script>
在示例中,我们同样通过 reactive 创建了一个响应式对象 state,并监听 state.count的变化。与 watch不同的是,这里我们使用了 watchEffect。每当 count 发生变化时,回调函数会自动执行并打印。
与 watch 相比,watchEffect 的优势在于它不需要手动指定依赖,当依赖的响应式数据发生变化时,它会自动重新执行;这使得它非常适合用于处理简单的、副作用较少的逻辑。
watch 和 watchEffect 的区别
虽然 watch 和 watchEffect 都可以用于监听响应式数据的变化,但两者之间还是有一些区别:
- 依赖追踪方式:watch 需要手动指定依赖,而 watchEffect 会自动追踪响应式依赖。这使得 watchEffect 更加自动化,但也更容易引入一些意外的副作用。
- 使用场景:watch 更适合用于需要明确控制依赖关系的复杂逻辑,而 watchEffect 更适合用于简单的副作用管理,尤其是在 setup 函数内部。
- 回调参数:watch 的回调函数接收新值和旧值两个参数,而 watchEffect 的回调函数没有参数,因为它关注的是整个副作用的执行过程。
如何选择 watch和watchEffect
- 选择 watch:当你需要在某个具体的数据变化时执行特定的操作,并且需要访问旧值和新值时,可以选择 watch。例如,数据的验证、API 请求等场景。
- 选择 watchEffect:当你需要根据多种响应式数据的变化进行综合处理,并且这种处理不依赖于旧值和新值的对比时,可以选择 watchEffect。例如,简单的日志记录、DOM 操作等场景。