Axios封装

Axios是 web 开发中最常用到的ajax操作库,其内置的方法有很多,进过二次封装后,可以有效的提高我们的工作效率,同时对我们的代码质量也是有很大影响。

一、axios封装

1.1 HttpClientConfig类型定义
httpClientConfig.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/*
* @Date: 2025-02-23 11:30:23
* @LastEditors: odinsam 123679@qq.com
* @LastEditTime: 2025-02-23 13:38:17
* @FilePath: /odin-node-util/lib/src/axios/httpClientConfig.ts
* @Description: HttpClientConfig
*/

import { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from "axios";

// 定义配置接口
export interface HttpClientConfig {
baseURL?: string;
timeout?: number;
token?: string;// 是否自动添加 token
requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
responseInterceptor?: (response: AxiosResponse<any, any>) => AxiosResponse<any, any> | Promise<AxiosResponse<any, any>>;
errorInterceptor?: (error: AxiosError) => Promise<never>;
}

1.2 odinAxios封装
odinAxios.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { type HttpClientConfig } from './httpClientConfig';

/*
* @Date: 2025-02-23 11:30:23
* @LastEditors: odinsam 123679@qq.com
* @LastEditTime: 2025-02-24 12:21:54
* @FilePath: /odin-node-util/lib/src/axios/odinAxios.ts
* @Description: odinAxios
*/

class odinAxios {
private instance: AxiosInstance;
private requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;

constructor(httpClientConfig: HttpClientConfig) {
// 创建 Axios 实例
this.instance = axios.create({
baseURL: httpClientConfig.baseURL, // 默认基础地址
timeout: httpClientConfig.timeout, // 默认超时时间
headers: {
'Content-Type': 'application/json',
},
});

// 保存用户自定义的拦截器
this.requestInterceptor = httpClientConfig.requestInterceptor;

// 请求拦截器
this.instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 如果配置了 withToken,自动添加 token
if (httpClientConfig.token != null) {
config.headers.Authorization = `Bearer ${httpClientConfig.token}`;
}

// 调用用户自定义的请求拦截器(如果存在)
if (this.requestInterceptor) {
return this.requestInterceptor(config);
}

return config;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);

// 响应拦截器
this.instance.interceptors.response.use(
(response: AxiosResponse<any, any>) => {
// 如果用户提供了自定义的响应拦截器,调用它
if (httpClientConfig.responseInterceptor) {
return httpClientConfig.responseInterceptor(response);
}
// 默认处理逻辑
if (response.data.code !== 200) {
return Promise.reject(response.data);
}
return response.data;
},
(error: AxiosError) => {
// 如果用户提供了自定义的错误拦截器,调用它
if (httpClientConfig.errorInterceptor) {
return httpClientConfig.errorInterceptor(error);
}
// 默认错误处理逻辑
if (error.response) {
switch (error.response.status) {
case 401:
console.error('未授权,请重新登录');
break;
case 404:
console.error('请求的资源不存在');
break;
case 500:
console.error('服务器内部错误');
break;
default:
console.error('请求失败');
}
} else {
console.error('网络错误,请检查网络连接');
}
return Promise.reject(error);
}
);
}

// 封装 GET 请求
public get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T, any>> {
return this.instance.get<T>(url, config);
}

// 封装 POST 请求
public post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T, any>> {
return this.instance.post<T>(url, data, config);
}

// 封装 PUT 请求
public put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T, any>> {
return this.instance.put<T>(url, data, config);
}

// 封装 DELETE 请求
public delete<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T, any>> {
return this.instance.delete<T>(url, config);
}
}

export default odinAxios;

二、调用示例

2.1 定义 axios config 配置
axiosConfig.ts
1
2
3
4
5
6
7
8

import type { HttpClientConfig } from "odin-node-util/lib/src/axios/httpClientConfig";

export const AxiosConfig: HttpClientConfig = {
baseURL: "https://odinsam.usemock.com/",
timeout: 1000
}

2.2 前端项目 api 封装类
axiosApi.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import { AxiosConfig } from "@/config/axiosConfig";
import odinAxios from "odin-node-util/lib/src/axios/odinAxios";

/*
* @Date: 2025-02-23 14:00:06
* @LastEditors: odinsam 123679@qq.com
* @LastEditTime: 2025-02-24 10:23:16
* @FilePath: /vue3Template/ts/src/axios/axiosApi.ts
* @Description: axiosApi
*/
const axiosApi = new odinAxios(AxiosConfig);

export function getUser<T>() {
return axiosApi.get<T>('/user');
}

2.3 vue 页面或 hooks 调用
hooks调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

import { getUser } from "@/axios/axiosApi"
import StringUtil from "odin-node-util/lib/src/utils/StringUtil";
import { ref } from "vue";

/*
* @Date: 2025-02-23 14:02:36
* @LastEditors: odinsam 123679@qq.com
* @LastEditTime: 2025-02-23 14:33:33
* @FilePath: /vue3Template/ts/src/hooks/useUser.ts
* @Description:
*/

// 后端返回data类型
interface IUser {
user: string
}

export default function () {
let userName = ref('姓名')
function getUserName() {
getUser<IUser>().then(res => {
userName.value = res.data.user;

})
}
return {
userName, getUserName
}
}