Prospect summary:
ts simply encapsulates axios, unified API
to configure switch interceptors in config
Loading is divided into full-screen loading and partial loading.
Setting loading in axios can only set full-screen loading, because local loading requires the current local dom, and obviously the element dom that initiates the request cannot be obtained in axios.
Encapsulating loading interceptor
- Request interceptor to enable loading
- Response interceptor closes loading
- Note: Loading should be turned off regardless of whether the request succeeds or fails, so loading must be turned off in both callbacks of the response interceptor.
import {
AxiosError, AxiosResponse } from "axios";
import {
ElLoading } from "element-plus";
import {
MyInternalAxiosRequestConfig } from "./request";
/**
* el-loading 有两种方式调用:指令和服务。
* 指令可以绑定到元素上,局部loading
* 此处以服务方式调用loading,并且根据请求配置 showLoading 来决定请求是否开启loading
* 此loading在全局拦截器生效,服务方式默认就是全屏
*/
/* 全局请求 loading(服务方式调用) */
let loadingInstance: ReturnType<typeof ElLoading.service>;
const startElementLoading = () => {
loadingInstance = ElLoading.service({
fullscreen: true,
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)"
// spinner: 自定义加载图标类名
// customClass: Loading 的自定义类名
});
};
const endElementLoading = (loadingInstance: ReturnType<typeof ElLoading.service>) => loadingInstance.close();
/**
* 开启loading
* @param {import("..").AxiosRequestConfig} config
* @returns
*/
export function showLoading(config: MyInternalAxiosRequestConfig) {
if (config.showLoading === false) return config;
startElementLoading();
return config;
}
/**
* 请求成功关闭 loading
* @param {import("axios").AxiosResponse} res
* @returns
*/
export function closeLoadingOnFulfilled(res: AxiosResponse) {
if (loadingInstance) endElementLoading(loadingInstance);
return res;
}
/**
* 请求失败关闭 loading
* @param {import("axios").AxiosError} err
* @returns
*/
export function closeLoadingOnRejected(err: AxiosError) {
if (loadingInstance) endElementLoading(loadingInstance);
throw err;
}
Configure the loading switch in config
const DEFAULT_EXTRA_FEATURE_CONFIG = {
showLoading: true, showMessage: true, retry: true };
/** 扩展 axios 的请求配置类型 */
export interface MyAxiosRequestConfig<TReqBodyData = any> extends AxiosRequestConfig<TReqBodyData> {
showLoading?: boolean;
showMessage?: boolean;
retry?: boolean;
}
/** 给拦截器使用 */
export interface MyInternalAxiosRequestConfig extends InternalAxiosRequestConfig {
showLoading?: boolean;
showMessage?: boolean;
retry?: boolean;
}
Register the loading interceptor after axios is instantiated
import HttpRequest from "./http/request";
import {
compareUrl, filterFulfilledUrlOnFulfilled, filterFulfilledUrlOnRejected } from "./http/debounceReq";
import {
closeLoadingOnFulfilled, closeLoadingOnRejected, showLoading } from "./http/loading";
import {
responseMessageOnFulfilled } from "./http/message";
import {
getTokenResponseInterceptor, setAccessTokenRequestInterceptor } from "./http/token";
import {
retryRequest } from "./http/retryRequest";
const httpRequest = new HttpRequest({
baseURL: import.meta.env.VITE_APP_API_BASE_URL,
timeout: import.meta.env.VITE_APP_API_TIMEOUT
});
// loading
httpRequest.getInstance().interceptors.request.use(showLoading);
httpRequest.getInstance().interceptors.response.use(closeLoadingOnFulfilled, closeLoadingOnRejected);
export default httpRequest;
```