如何在 Vue.js 中使用 VueUse 中止 API 请求和处理错误
引言
在 Vue 应用程序中处理异步操作时,高效管理请求至关重要,特别是在处理可能长时间运行或不必要的请求时。在本文中,我们将探讨如何使用VueUse中止请求并处理这些被中止请求抛出的错误。
问题
在现代 Web 应用程序中,进行多个API 调用来获取数据是很常见的。然而,在某些情况下,我们可能想要取消正在进行的请求,例如当用户离开页面或当新请求取代现有请求时。此外,我们需要处理中止这些请求时可能发生的错误,以确保流畅的用户体验。
背景
VueUse 提供了一个强大的useFetch
可组合函数,允许我们进行具有内置中止功能的 HTTP 请求。让我们看看如何利用这个特性:
typescript
const { abort, canAbort } = useFetch(url);
setTimeout(() => {
if (canAbort.value) abort();
}, 100);
在这个例子中,我们可以使用useFetch
提供的abort
函数来中止请求。canAbort
属性表示请求是否可以被中止。
我们还可以为中止请求设置自动超时:
typescript
const { data } = useFetch(url, { timeout: 100 });
这将在 100 毫秒后自动中止请求。
解决方案
现在,让我们实现一个解决方案,演示如何在Vue 组件中中止请求并处理错误。我们将创建一个获取消息的组件,并允许用户通过多次点击按钮来取消请求。
vue
<template>
<div>
<button @click="getMessages">获取消息</button>
<div v-if="loading">加载中...</div>
<ul v-else>
<li v-for="message in messages" :key="message.id">
{{ message.text }}
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useFetch } from '@vueuse/core';
import { defineStore } from 'pinia';
interface Message {
id: number;
text: string;
}
const useStore = defineStore('main', {
state: () => ({
cancellableRequests: new Map<string, { abort: () => void }>(),
}),
});
const store = useStore();
const messages = ref<Message[]>([]);
const loading = ref(false);
const getMessages = async (): Message[] => {
try {
loading.value = true;
const url = '/api/messages';
const token = 'getMessages';
if (store.cancellableRequests.has(token)) {
store.cancellableRequests.get(token)?.abort();
store.cancellableRequests.delete(token);
}
const { execute, abort, data, error } = useFetch(url, {
immediate: false,
})
.get()
.json<{ messages: Message[] }>();
store.cancellableRequests.set(token, { abort });
await execute();
if (error.value) {
if error.value instanceof Error && error.value.name === 'AbortError') {
store.cancellableRquests.delete(token);
return []
}
throw new Error('出错了。请稍后再试。')
}
return data.value.messages;
} finally {
loading.value = false;
}
};
</script>
在这个例子中,我们创建了一个 Vue 组件,演示如何中止请求并处理错误:
- 我们定义了一个Pinia存储来管理可取消的请求。
getMessages
函数负责获取消息并处理请求生命周期。- 在发出新请求之前,我们检查是否存在具有相同令牌的现有请求,如果存在则中止它。
- 我们使用 VueUse 的
useFetch
来进行 API 调用。 - 我们将
abort
函数存储在 Pinia 存储中,允许我们在需要时取消请求。 - 我们处理错误,包括
AbortError
,这是在请求被取消时抛出的。 - 如果成功,我们返回获取的消息,如果请求被中止,则返回一个空数组。
- 最后,我们通过从存储中删除请求并将加载状态设置为 false 来进行清理。
这种实现允许高效管理 API 调用,防止不必要的网络请求,并改善整体用户体验。
结论
通过实施这个解决方案,我们成功地解决了最初的问题,即如何使用 VueUse 中止请求并处理它们抛出的错误。这种方法允许高效管理 API 调用,防止不必要的网络请求,并改善整体用户体验。