axios implements request loading effect

Insert image description here

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

  1. Request interceptor to enable loading
  2. 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;
```

Guess you like

Origin blog.csdn.net/qq_43220213/article/details/134194610