封装axios和loading组件
安装
bash
npm install antd -S
npm install axios -S代码说明
通过 axios 提供的请求拦截和响应拦截的接口,控制 loading 的显示或者隐藏。在此我还设置了没有网络和网络超时的提示信息
采用 DOM 来实现 loading 效果,message 组件来进行消息提示
定义变量 requestCount 作为计数器,确保同一时刻如果有多个请求的话,不会同时添加多个 loading,而是只有 1 个,并在所有请求结束后才会隐藏 loading。
默认所有请求都会自动有 loading 效果。如果某个请求不需要 loading 效果,可以在请求 headers 中设置 isLoading 为 false。
步骤
封装request.ts
ts
import axios, { type AxiosRequestConfig } from "axios";
import { message } from "antd";
const Axios = axios.create({
// baseURL: import.meta.env.VITE_BASE_URL, // 设置请求的 base url
timeout: 20000, // 设置超时时长
});
// 设置 post 请求头
Axios.defaults.headers.post["Content-Type"] =
"application/x-www-form-urlencoded;charset=UTF-8";
// 当前正在请求的数量
let requestCount = 0;
// 显示 loading(纯 DOM,不渲染 React 组件,避免 .tsx / Fast Refresh 限制)
function showLoading() {
if (requestCount === 0 && !document.getElementById("global-loading")) {
const dom = document.createElement("div");
dom.id = "global-loading";
dom.style.cssText =
"position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(24,39,39,.2);z-index:9999;";
dom.innerHTML =
'<div style="font-size:14px;color:#1677ff;">加载中...</div>';
document.body.appendChild(dom);
}
requestCount++;
}
// 隐藏 loading
function hideLoading() {
requestCount--;
if (requestCount <= 0) {
requestCount = 0;
document.getElementById("global-loading")?.remove();
}
}
// 请求前拦截
Axios.interceptors.request.use(
(config) => {
// requestCount 为 0 才创建 loading,避免重复创建
if (config.headers.isLoading !== false) {
showLoading();
}
return config;
},
(err) => {
if (err.config?.headers?.isLoading !== false) {
hideLoading();
}
return Promise.reject(err);
},
);
// 返回后拦截
Axios.interceptors.response.use(
(res) => {
if (res.config.headers.isLoading !== false) {
// hideLoading();
}
return res;
},
(err) => {
if (err.config?.headers?.isLoading !== false) {
// hideLoading();
}
if (err.message === "Network Error") {
message.warning("网络连接异常!");
}
if (err.code === "ECONNABORTED") {
message.warning("请求超时,请重试");
}
return Promise.reject(err);
},
);
// GET 请求
export function get<T = unknown>(
url: string,
params?: object,
config?: AxiosRequestConfig,
) {
return Axios.get<T>(url, { params, ...config }).then((res) => res.data);
}
// POST 请求
export function post<T = unknown>(
url: string,
data?: object,
config?: AxiosRequestConfig,
) {
return Axios.post<T>(url, data, config).then((res) => res.data);
}
export default Axios;页面里面使用
tsx
import { get } from "@/api/request";
import { useEffect } from "react";
function HomePage() {
useEffect(() => {
get("https://httpbin.org/delay/6").then((res) => console.log(res));
}, []);
return (
<div>
<h1>Home Page</h1>
</div>
);
}
export default HomePage;