调用组件封装axios和loading
安装
bash
npm install antd -S
npm install axios -S新建loading组件
路径
bash
src
├── components
│ ├── common
│ ├── Loading
│ ├── index.css
│ ├── index.tsx
│ ├── loading.tsindex.css
css
.global-loading-mask {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.6);
z-index: 9999;
}index.tsx
tsx
import { Spin } from "antd";
import "./index.css";
export default function Loading() {
return (
<div className="global-loading-mask">
<Spin tip="加载中666..." size="large">
<div style={{ width: 200, height: 100 }} />
</Spin>
</div>
);
}loading.ts
ts
import { createRoot, type Root } from "react-dom/client";
import { createElement } from "react";
import Loading from "./index";
let container: HTMLDivElement | null = null;
let root: Root | null = null;
// 挂载 loading
export function mountLoading() {
if (container) return;
container = document.createElement("div");
container.id = "global-loading";
document.body.appendChild(container);
root = createRoot(container);
root.render(createElement(Loading));
}
// 卸载 loading
export function unmountLoading() {
if (!container) return;
// 延迟卸载,避免在同一渲染周期内 unmount 报警告
const target = container;
const targetRoot = root;
container = null;
root = null;
setTimeout(() => {
targetRoot?.unmount();
target.remove();
});
}封装request.ts
在api目录下新建request.ts
ts
import axios, { type AxiosRequestConfig } from "axios";
import { message } from "antd";
import {
mountLoading,
unmountLoading,
} from "@/components/common/Loading/loading";
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
function showLoading() {
if (requestCount === 0) {
mountLoading();
}
requestCount++;
}
// 隐藏 loading
function hideLoading() {
requestCount--;
if (requestCount <= 0) {
requestCount = 0;
unmountLoading();
}
}
// 请求前拦截
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;