一、文档结构
二、具体代码
//index.t最外部
//service统一出口
import HYRequest from './request';
import { BASE_URL, TIME_OUT } from './request/config';
const hyRequest = new HYRequest({
baseURL: BASE_URL,
timeout: TIME_OUT
});
export default hyRequest;
//request中index.ts
import axios, { AxiosInstance } from 'axios';
import { HYRequestInterceptors, HYRequestConfig } from './type';
import { ElLoading } from 'element-plus';
/**
* 三种拦截器:1、全局拦截器 2、实例拦截器 3、单个请求拦截器
* 控制显示loading:
* 默认为显示,
* 可以在创建请求实例时,指定是否显示,
* 也可以对单个请求进行指定是否显示
*/
const DEFAULT_LOADING = true;
class HYRequest {
instance: AxiosInstance;
interceptors?: HYRequestInterceptors;
showLoading: boolean;
loading?: any;
constructor(config: HYRequestConfig) {
// 创建axios实例
this.instance = axios.create(config);
// 保存基本信息
this.interceptors = config.interceptors;
this.showLoading = config.showLoading ?? DEFAULT_LOADING;
//从config中取出的拦截器是对应实例具有的拦截器
this.instance.interceptors.request.use(
this.interceptors?.requestInterceptor as AxiosInstance,
this.interceptors?.requestInterceptorCatch
);
this.instance.interceptors.response.use(
this.interceptors?.responseInterceptor,
this.interceptors?.responseInterceptorCatch
);
// 添加所有实例具有的拦截器
this.instance.interceptors.request.use(
(config) => {
// 控制实例的loading是否显示,默认为显示
if (this.showLoading) {
this.loading = ElLoading.service({
lock: true,
text: '正在请求数据。。。。',
background: 'rgb(0, 0, 0, 0.5)'
});
}
return config;
},
(err) => {
return err;
}
);
this.instance.interceptors.response.use(
(res) => {
// 关闭loading
this.loading?.close();
return res.data;
},
(err) => {
// 关闭loading
this.loading?.close();
return err;
}
);
}
request<T>(config: HYRequestConfig<T>): Promise<T> {
return new Promise((resolve, reject) => {
// 单个请求拦截器
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config);
}
// 处理单个请求是否显示loading
if (config.showLoading === false) {
this.showLoading = false;
}
this.instance
.request<any, T>(config)
.then((res) => {
// 单个请求拦截器
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res);
}
//将showLoading设置为true,这样不会影响下一个请求
this.showLoading = DEFAULT_LOADING;
// 返回结果
resolve(res);
})
.catch((err) => {
//将showLoading设置为true,这样不会影响下一个请求
this.showLoading = DEFAULT_LOADING;
// 返回结果
reject(err);
});
});
}
get<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request({ ...config, method: 'GET' });
}
post<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request({ ...config, method: 'POST' });
}
patch<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request({ ...config, method: 'PATCH' });
}
delete<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request({ ...config, method: 'DELETE' });
}
}
export default HYRequest;
//type.ts
import { AxiosRequestConfig, AxiosResponse } from 'axios';
export interface HYRequestInterceptors<T = AxiosResponse> {
requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig;
requestInterceptorCatch?: (err: any) => any;
responseInterceptor?: (res: T) => T;
responseInterceptorCatch?: (err: any) => any;
}
export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: HYRequestInterceptors<T>;
showLoading?: boolean;
}
//config.ts
let BASE_URL = '';
const TIME_OUT = 100000;
if (process.env.NODE_ENV == 'development') {
BASE_URL = '';
} else if (process.env.NODE_ENV == 'production') {
BASE_URL = 'http://baidu.com/production';
} else {
BASE_URL = 'http://baidu.com/test';
}
export { BASE_URL, TIME_OUT };
三、使用
import hyRequest from './service';
hyRequest
.get({
url: '/getUserList',
showLoading: false
})
.then((res) => {
console.log(res);
});
四、解释
其中有三种拦截器,分别为实例拦截器,全局拦截器和单个请求拦截器
其中有loading加载,分为实例loading和单个请求loading,可自由配置