在Vue 3.x中,如果你想要在组件卸载时自动取消正在进行的fetch
请求(或其他异步操作),你可以通过结合watch
或watchEffect
的清理函数来实现。然而,Vue 3.5本身并没有直接引入名为onWatcherCleanup
的API。不过,watch
和watchEffect
函数都提供了返回一个停止观察的函数,这可以用于清理操作。
![图片[1]_基于NexusPHP的完整PT建站解决方案及功能特性概述_知途无界](https://zhituwujie.com/wp-content/uploads/2024/09/d2b5ca33bd20240920094024.png)
以下是一个基于Vue 3.x的示例,展示了如何封装一个自动取消的fetch
函数,该函数在组件卸载时会自动取消正在进行的请求。
1. 使用watchEffect
和abortController
在这个例子中,我们将使用AbortController
来取消fetch
请求,并通过watchEffect
的清理函数来管理它。
<template><div><h1>数据加载示例</h1><p v-if="data">数据: {{ data }}</p><p v-else>加载中...</p></div></template><script setup>import { ref, watchEffect, onUnmounted } from 'vue';const data = ref(null);let abortController = null;const fetchData = async () => {if (abortController) abortController.abort(); // 取消之前的请求abortController = new AbortController();const signal = abortController.signal;try {const response = await fetch('https://api.example.com/data', { signal });if (!response.ok) throw new Error('Network response was not ok');const json = await response.json();data.value = json;} catch (error) {if (error.name === 'AbortError') {console.log('Fetch aborted');} else {console.error('Fetch error:', error);}}};watchEffect(() => {// 这里可能基于某些响应式数据的变化来触发fetchData// 但为了演示,我们直接调用它fetchData();// 清理函数return () => {if (abortController) {abortController.abort();abortController = null;}};});// 如果你确定不需要通过watchEffect的依赖数组来触发fetchData,// 你也可以直接使用onUnmounted来清理onUnmounted(() => {if (abortController) {abortController.abort();abortController = null;}});</script><template> <div> <h1>数据加载示例</h1> <p v-if="data">数据: {{ data }}</p> <p v-else>加载中...</p> </div> </template> <script setup> import { ref, watchEffect, onUnmounted } from 'vue'; const data = ref(null); let abortController = null; const fetchData = async () => { if (abortController) abortController.abort(); // 取消之前的请求 abortController = new AbortController(); const signal = abortController.signal; try { const response = await fetch('https://api.example.com/data', { signal }); if (!response.ok) throw new Error('Network response was not ok'); const json = await response.json(); data.value = json; } catch (error) { if (error.name === 'AbortError') { console.log('Fetch aborted'); } else { console.error('Fetch error:', error); } } }; watchEffect(() => { // 这里可能基于某些响应式数据的变化来触发fetchData // 但为了演示,我们直接调用它 fetchData(); // 清理函数 return () => { if (abortController) { abortController.abort(); abortController = null; } }; }); // 如果你确定不需要通过watchEffect的依赖数组来触发fetchData, // 你也可以直接使用onUnmounted来清理 onUnmounted(() => { if (abortController) { abortController.abort(); abortController = null; } }); </script><template> <div> <h1>数据加载示例</h1> <p v-if="data">数据: {{ data }}</p> <p v-else>加载中...</p> </div> </template> <script setup> import { ref, watchEffect, onUnmounted } from 'vue'; const data = ref(null); let abortController = null; const fetchData = async () => { if (abortController) abortController.abort(); // 取消之前的请求 abortController = new AbortController(); const signal = abortController.signal; try { const response = await fetch('https://api.example.com/data', { signal }); if (!response.ok) throw new Error('Network response was not ok'); const json = await response.json(); data.value = json; } catch (error) { if (error.name === 'AbortError') { console.log('Fetch aborted'); } else { console.error('Fetch error:', error); } } }; watchEffect(() => { // 这里可能基于某些响应式数据的变化来触发fetchData // 但为了演示,我们直接调用它 fetchData(); // 清理函数 return () => { if (abortController) { abortController.abort(); abortController = null; } }; }); // 如果你确定不需要通过watchEffect的依赖数组来触发fetchData, // 你也可以直接使用onUnmounted来清理 onUnmounted(() => { if (abortController) { abortController.abort(); abortController = null; } }); </script>
注意
- 在这个例子中,我使用了
watchEffect
来演示如何自动触发fetchData
函数并在组件卸载时取消请求。然而,如果你的fetch
请求是基于某些响应式数据的变化而触发的,你应该在watchEffect
中添加依赖项。但在这个简单示例中,我直接调用了fetchData
来模拟请求。 - 我也展示了如何在
onUnmounted
中手动清理,这通常是更直接的方法,特别是当你不需要基于响应式数据的变化来触发fetch
时。 - 使用
AbortController
是取消网络请求的一种现代且有效的方式,它允许你中断正在进行的请求,这在处理如用户导航离开页面或组件卸载时特别有用。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END
暂无评论内容