Vue3 Axios 请求封装与错误处理
一、为什么选择Axios
Axios的优势不必多说,但是对于在vue项目中使用,它有以下优势:
二、配置 Axios 实例
首先,创建一个axios.ts文件,用于配置 Axios 实例。这样可以确保所有 HTTP 请求共享统一的全局配置。
import axios, { type AxiosInstance, type InternalAxiosRequestConfig, type AxiosResponse } from ‘axios’;
const apiClient: AxiosInstance = axios.create({
baseURL: //根据项目需求配置对应的基地址
timeout: //根据项目需求配置对应的请求超时时间
headers: {
‘Content-Type’: ‘application/json’,
},
});
// 添加请求拦截器
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 根据存储token的方式获取
const token = localStorage.getItem(‘token’);
if (token && config.headers) {
// 添加到请求头上
config.headers.token = token;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 添加响应拦截器
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
return response.data;
},
(error) => {
// 全局错误处理
if (error.response && error.response.status === 401) {
// 跳转登录页的逻辑,例如使用router
}
// 还可以有其他类型的错误处理
return Promise.reject(error);
}
);
export default apiClient;
三、封装通用的请求 Hook:useRequsst
为了在组件中更优雅地、方便快捷地发起请求,我们封装了一个通用的 Hook,支持灵活的请求方法、数据处理和错误管理。
import { shallowRef, type Ref } from “vue”;
//从刚才创建的axios.ts中获取实例
import apiClient from “../api/axios”;
// 定义 HTTP 方法的类型
type HttpMethod = “get” | “post” | “put” | “delete”;
interface RequestOptions {
url: string;
method?: HttpMethod;
requestData?: Record<string, unknown>;
}
// 定义 useRequest 返回的类型,包括有 请求成功返回的数据、错误信息、加载信息、发送请求的函数
interface UseRequestResult
data: Ref<T | null>;
error: Ref<Error | null>;
loading: Ref
executeRequest: (options: RequestOptions) => Promise
}
export function useRequest<T = unknown>(): UseRequestResult
const data = shallowRef<T | null>(null);
const error = shallowRef<Error | null>(null);
const loading = shallowRef
const executeRequest = async ({
url,
// 设置默认值
method = "get",
requestData,
}: RequestOptions): Promise<void> => {
loading.value = true;
error.value = null;
try {
const response = await apiClient.request<T>({
url,
method,
...(method !== "get" ? { data: requestData } : {}),
});
data.value = response;
} catch (err) {
error.value = err instanceof Error ? err : new Error(String(err));
} finally {
loading.value = false;
}
};
return {
data,
error,
loading,
executeRequest,
};
}
封装成hook的优势:
1、参数化请求
通过参数动态指定发送请求的url和method
2、状态管理
loading :请求状态(true表示在请求中,false表示未在请求中)
error:储存请求返回的错误信息
data:储存请求返回的数据
3、类型管理
使用ts限定了请求数据、响应数据以及状态数据的格式,规避了类型冲突问题
四、使用实例:
使用封装的hook创建用户:

