vue3从精通到入门11:高级侦听器watchEffect

使用 TypeScript 和 <script setup> 语法糖结合 watchEffect 可以提供强大的类型检查和更简洁的组件逻辑。watchEffect 会自动收集其执行过程中访问到的响应式依赖,并在这些依赖变化时重新运行回调函数。

watchEffect用法

watchEffect()watch 的作用基本一致,用于监听响应性数据的变化,并根据变化做一些响应的业务逻辑。

html 复制代码
<template>  
  <div>  
    <p>Count: {{ count }}</p>  
    <button @click="increment">Increment</button>  
  </div>  
</template>  
  
<script setup lang="ts">  
import { ref, watchEffect } from 'vue';  
  
// 定义响应式引用及其类型  
const count = ref<number>(0);  
  
// 使用 watchEffect 监听 count 的变化  
watchEffect(() => {  
  console.log('watchEffect triggered');  
  console.log('Count is now:', count.value);  
});  
  
// 定义一个方法来增加 count 的值  
const increment = () => {  
  count.value++;  
};  
</script>

我们使用了 ref<number>(0) 来创建一个初始值为 0 的响应式引用 count,并明确指定其类型为 numberwatchEffect 在其回调函数内部访问了 count.value,因此当 count 的值变化时,watchEffect 的回调函数会自动重新执行。

如果你想要在 watchEffect 的回调函数中访问组件的 props 或其他响应式状态,并且这些状态具有复杂的类型,你可以使用 TypeScript 的接口或类型别名来定义这些状态的类型。

例如:

html 复制代码
<script setup lang="ts">  
import { ref, watchEffect } from 'vue';  
  
interface User {  
  name: string;  
  age: number;  
  email: string;  
}  
  
const user = ref<User>({  
  name: 'John Doe',  
  age: 30,  
  email: 'johndoe@example.com',  
});  
  
watchEffect(() => {  
  console.log('User data changed:', user.value);  
});  
</script>

onInvalidate清除副作用:

onInvalidate 是一个函数,它接收一个回调函数作为参数。这个回调函数会在 watchEffect 的副作用函数重新执行之前被调用,或者在组件卸载时(如果副作用函数是在 setup 函数或生命周期钩子中使用的 watchEffect)被调用。这样,我们就可以在这个回调函数中执行必要的清理操作。

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const count = ref(0);  
  
watchEffect(onInvalidate => {  
  const timer = setInterval(() => {  
    console.log(`Count is: ${count.value}`);  
  }, 1000);  
  
  onInvalidate(() => {  
    clearInterval(timer);  
    console.log('Timer has been cleared');  
  });  
});

在这个例子中,我们创建了一个定时器,用于每秒打印 count 的值。然后,我们使用 onInvalidate 注册了一个清理函数,当 watchEffect 的副作用函数重新执行或组件卸载时,这个清理函数会被调用,从而清除定时器。

watchEffect的使用场景

1. 监听多个响应式依赖的变化

当需要监听多个响应式数据的变化,并且没有明确的监听顺序时,watchEffect 是一个很好的选择。它会自动收集其执行过程中访问到的所有响应式依赖,并在这些依赖变化时重新运行回调函数。

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const count = ref(0);  
const name = ref('');  
  
watchEffect(() => {  
  console.log(`Count: ${count.value}, Name: ${name.value}`);  
});  
  
// 当 count 或 name 发生变化时,回调函数都会重新执行

2. 异步副作用操作

当需要在响应式数据变化时执行异步操作(如 API 请求)时,watchEffect 可以很好地处理。因为 watchEffect 的回调函数是异步执行的,你可以在回调中安全地使用 async/await

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const searchQuery = ref('');  
  
watchEffect(async onInvalidate => {  
  const result = await fetchData(searchQuery.value);  
  // 处理结果...  
  
  onInvalidate(() => {  
    // 清理操作,比如取消请求等  
  });  
});

3. 无需显式指定依赖项

watch 不同,watchEffect 不需要显式指定要监听的依赖项。它会自动收集,这使得它在某些场景下更为方便。例如,当你不确定要监听哪些依赖项,或者依赖项较多时。

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const form = reactive({  
  name: '',  
  email: '',  
  password: ''  
});  
  
watchEffect(() => {  
  validateForm(form);  
});  
  
// 当 form 对象中的任何属性变化时,validateForm 都会被调用

4. 对副作用进行清理

当副作用函数需要执行清理操作(如取消定时器、移除事件监听器等)时,可以使用 onInvalidate。这在 watchEffect 中是非常有用的,因为它提供了一种机制来确保在组件卸载或副作用函数重新运行之前执行必要的清理操作。

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const count = ref(0);  
  
watchEffect(onInvalidate => {  
  const timer = setInterval(() => {  
    console.log(count.value);  
  }, 1000);  
  
  onInvalidate(() => {  
    clearInterval(timer);  
  });  
});

5. 初始执行回调

默认情况下,watchEffect 在组件挂载后会立即执行其回调函数一次。这可以用于执行初始的副作用操作,如初始化状态或发送初始请求。

javascript 复制代码
import { ref, watchEffect } from 'vue';  
  
const isLoaded = ref(false);  
  
watchEffect(() => {  
  fetchData().then(() => {  
    isLoaded.value = true;  
  });  
});  
  
// 组件挂载后,fetchData 会被立即调用

总结

watchEffect 是一个强大的工具,它简化了对多个响应式依赖的监听,并提供了对异步操作和副作用清理的支持。当你不确定要监听哪些具体依赖项,或者需要执行初始副作用操作时,watchEffect 是一个很好的选择。然而,如果你需要更细粒度地控制依赖项的变化,或者需要更多的选项来定制侦听器行为,那么 watch 函数可能更适合你的需求。

相关推荐
崔庆才丨静觅30 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅3 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊3 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax