源码地址:GitHub / 码云
axios封装
🎯 目标
封装axios相关工具类,实现功能包含axios配置、拦截器、发送请求、中止请求。
🍸 准备
调整文件&目录
在 /src/utils 目录下创建 axios 封装类。
utils文件目录结构如下:
📁 src
----📁 utils
--------📁 http
------------📄 abort-request.ts
------------📄 custom-axios.ts
------------📄 index.ts
------------📄 types.ts
🌈 Coding
定义类型
types.ts 代码如下:
import { AxiosRequestConfig, AxiosResponse } from "axios";
export interface InterceptorConfig<T> {
enableAbortRequest?: boolean,
interceptorRequest?: (value: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>
interceptorRequestRejected?: (error: any) => any
interceptorResponse?: ((value: AxiosResponse<T>) => AxiosResponse<any> | Promise<AxiosResponse<T>>)
interceptorResponseRejected?: (error: any) => any
}
export interface CustomRequest<T> {
customConfig?: AxiosRequestConfig;
interceptorConfig: InterceptorConfig<T>
}
export interface CustomResponse {
message: string;
code: number;
result: any
}
中止请求类
abort-request.ts 结构 如下(代码不全,文章顶部有源码地址):
export class AbortRequest {
private pendingMap = new Map<string, Canceler>()
genPendingKey(config: AxiosRequestConfig): string
addPending(config: AxiosRequestConfig)
removePending(pendingKey: string)
clearPending()
abort(pendingKey: string): boolean
}
自定义 axios 类
custom-axios.ts 结构 如下(代码不全,文章顶部有源码地址):
export class CustomAxios<T> {
private instance: AxiosInstance
private abortRequest: AbortRequest
constructor(customRequest: CustomRequest<T>)
useInterceptors(config: InterceptorConfig<T>)
request(config: AxiosRequestConfig): Promise<AxiosResponse<T>>
get(url: string, params?: object, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
post(url: string, data?: object, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
put(url: string, data?: object, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
delete(url: string, data?: object, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
}
实例化自定义 axios 对象
上面已经将工具类代码封装好,现在我们需要实例化一个对象,并对外暴露使用。index.ts 代码如下:
import { AxiosRequestConfig, AxiosResponse } from 'axios';
import { CustomAxios } from './custom-axios';
import { CustomResponse } from './types';
const customAxios = new CustomAxios<CustomResponse>({
customConfig: {
baseURL: import.meta.env.VITE_BASE_URL as string,
timeout: 10 * 1000,
timeoutErrorMessage: '请求超时,请稍后再试。'
},
interceptorConfig: {
enableAbortRequest: true,
interceptorRequest: (config: AxiosRequestConfig) => {
console.log('执行请求拦截器...');
return config
},
interceptorResponse: (res: AxiosResponse) => {
console.log('执行响应拦截器...');
return res
}
}
});
export default customAxios;
Demo 组件
最后让 Demo 组件 Axios.vue 来调用和验证,代码如下:
<template>
<!-- ↓HTTP请求demo -->
<div>
<h2>HTTP请求</h2>
<button @click="httpGet">get请求</button>
<button @click="httpPost">post请求</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import http from "@/utils/http/index";
export default defineComponent({
name: "Axios",
setup() {
const httpGet = () => {
http
.get("https://jsonplaceholder.typicode.com/posts/1")
.then((response: any) => {
console.log(response);
});
};
const httpPost = () => {
http
.post("https://jsonplaceholder.typicode.com/posts", {
keyword: "code",
})
.then((response: any) => {
console.log(response);
});
};
return {
httpGet,
httpPost,
};
},
});
</script>
🎭 结果
-
点击按钮发送get和post请求,控制台输出如下日志: addPending: post&https://jsonplaceholder.typicode.com/posts
custom-axios.ts:41 进入请求拦截器...
index.ts:22 执行请求拦截器...
abort-request.ts:27 removePending: post&https://jsonplaceholder.typicode.com/posts
custom-axios.ts:62 进入响应拦截器...
index.ts:27 执行响应拦截器...
{data: {…}, status: 201, statusText: "", headers: {…}, config: {…}, …}
-
快速点击两次按钮,会弹出“重复请求被取消”的提示框,控制台输出如下日志: addPending: post&https://jsonplaceholder.typicode.com/posts
custom-axios.ts:41 进入请求拦截器...
index.ts:22 执行请求拦截器...
abort-request.ts:42 abortRequest: post&https://jsonplaceholder.typicode.com/posts
custom-axios.ts:41 进入请求拦截器...
index.ts:22 执行请求拦截器...
custom-axios.ts:67 响应拦截器抛出异常...
:3000/#/home:1 Uncaught (in promise) Cancel {message: "重复请求被取消"}
Promise.then (async)
httpPost @ Axios.vue:31
_createVNode.onClick._cache.<computed>._cache.<computed> @ Axios.vue:6
callWithErrorHandling @ runtime-core.esm-bundler.js:155
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:164
invoker @ runtime-dom.esm-bundler.js:349
abort-request.ts:27 removePending: post&https://jsonplaceholder.typicode.com/posts
custom-axios.ts:62 进入响应拦截器...
index.ts:27 执行响应拦截器...
Axios.vue:32 {data: {…}, status: 201, statusText: "", headers: {…}, config: {…}, …}
-
配置 enableAbortRequest:false 关闭中止请求功能,点击按钮发送请求,控制台输出如下日志: 进入请求拦截器...
index.ts:22 执行请求拦截器...
custom-axios.ts:62 进入响应拦截器...
index.ts:27 执行响应拦截器...
Axios.vue:22 {data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
本文为博主原创文章,任何个人、团体、机构转载和摘录,请注明出处。
|