优雅地封装Axios库

在项目中对axios进行二次封装,实现更多的请求响应拦截功能

使用类进行封装

我们可以创建一个自己的请求类,使用axios.create()创建axios实例作为属性,在这个instance上面可以直接添加拦截器,这和原先没有封装的axios一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import axios from 'axios'
import type { AxiosInstance } from 'axios'
class MYRequest {
instance: AxiosInstance
this.instance.interceptors.request.use(
(config) => {
return config
},
(err) => {
return err
}
)

this.instance.interceptors.response.use(
(res) => {
return res.data
},
(err) => {
return err
}
)

添加自己的config

思路是我们可以通过这个类创建自己的实例,每个实例都可以传入自己的配置,达到不同的使用效果

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
 interface MYRequestInterceptors {
requestInterceptor?: (config: any) => any
requestInterceptorCatch?: (err: any) => any
responseInterceptor?: (res: any) => any
responseInterceptorCatch?: (err: any) => any
}
interface MYRequestConfig extends AxiosRequestConfig {
interceptors?: MYRequestInterceptors
}

class MYRequest {
instance: AxiosInstance
interceptors?: MYRequestInterceptors

constructor(config: MYRequestConfig) {
this.instance = axios.create(config)
//每个实例独有的config配置拦截器
this.interceptors = config.interceptors
this.instance.interceptors.request.use(
this.interceptors?.requestInterceptor,
this.interceptors?.requestInterceptorCatch
)
this.instance.interceptors.response.use(
this.interceptors?.responseInterceptor,
this.interceptors?.responseInterceptorCatch
)
}

为每个请求配置拦截器

对于每个请求,同时也会接受相应的config配置,我们可以调用这上面传入的拦截器函数,最后返回Promise对象

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
class MYRequest {

request<T = any>(config: MYRequestConfig): Promise<T> {
//为request请求使用单独的请求拦截器
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config)
}

return new Promise((resolve, reject) => {
this.instance
.request<any, T>(config)
.then((res) => {
//为request请求使用单独的响应拦截器
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res)
}
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}

get<T = any>(config: MYRequestConfig): Promise<T> {
return this.request({ ...config, method: 'GET' })
}
}

创建一个请求

最后我们使用这个类创建一个实例,传入可选的配置项、拦截器,在这个上面添加相应的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const myRequest = new MYRequest({
baseURL: BASE_URL,
timeout: TIME_OUT,
interceptors: {
requestInterceptor: (config) => {
//给每个请求添加token
const token = localCache.getCache(LOGIN_TOKEN)
if (config.headers && token) {
config.headers.Authorization = `bearer ${token}`
}
return config
}
}
})

export default myRequest
1
2
3
4
5
6
export function accountLoginRequest(account: IAccount) {
return myRequest.post({
url: '/login',
data: account
})
}

至此我们完成了axios的二次封装,我们仍可以在这上面增加一些配置,如区分生产环境和开发环境的config,增加全局的请求loading等。