- 通过 axios 提供的请求拦截和响应拦截的接口,控制 loading 的显示或者隐藏。
- 采用antd的Spin组件来实现loading效果,message组件来进行消息提示。
- 默认所有请求都会自动有 loading 效果。如果某个请求不需要 loading 效果,可以在请求 headers 中设置 isLoading 为false。
import axios from "axios";
import _isEmpty from "lodash/isEmpty";
import _omitBy from "lodash/omitBy";
import { getTimestamp } from "./utils";
import { message, Spin } from 'antd';
const { protocol } = window.location; // 协议
const { host } = window.location; // 主机
// 显示loading
const createLoading = () => {
let loadingWrapper = document.createElement("div");
loadingWrapper.setAttribute("id", "loading");
document.body.appendChild(loadingWrapper);
const SpinHtml = <Spin size="lg" spinning />;
render(React.cloneElement(SpinHtml), loadingWrapper);
return {
// 隐藏loading
hide() {
document.body.removeChild(loadingWrapper);
loadingWrapper = null;
},
};
};
// 区分环境
if (process.env.NODE_ENV === "development") {
// 若本地项目调试使用
axios.defaults.baseURL = `${protocol}//${host}/api`;
} else {
// 动态请求地址 协议 主机
axios.defaults.baseURL = `${protocol}//${host}`;
}
axios.defaults.timeout = 100000;
axios.defaults.withCredentials = true;
axios.defaults.headers["Content-Type"] = "application/json;charset=UTF-8";
axios.interceptors.request.use(
(config) => {
const ts = getTimestamp();
config.headers = {
"X-Requested-With": "XMLHttpRequest",
"Cache-Control": "no-cache",
Pragma: "no-cache",
ts,
...config.headers,
};
// if (Object.prototype.toString.call(config.data) !== '[object FormData]') {
// config.data = qs.stringify(config.data);
// }
return config;
},
(error) => Promise.reject(error)
);
axios.interceptors.response.use(
(response) => {
return response;
},
// 服务器状态码不是200的情况
(error) => {
return Promise.reject(error);
}
);
function filterParams(params) {
return _omitBy(params, (param) => {
const type = typeof param;
if (type === "number" || type === "boolean") {
return false;
}
if (type === "string") {
return param.trim() === "";
}
return _isEmpty(param);
});
}
export function request(config, showLoading = true) {
const { url, method, data, params, header } = config;
function createLoadingWrapper() {
if (showLoading) {
return createLoading();
}
return null;
}
let _loading = createLoadingWrapper();
function hideLoading() {
if (_loading) {
_loading.hide();
_loading = null;
}
}
return new Promise((resolve, reject) => {
let _params = null;
let _data = null;
if (method === "GET") {
_params = filterParams(params || data);
} else {
_data = data;
_params = filterParams(params);
}
axios({
method,
url,
data: _data,
params: _params,
headers: header,
})
.then((res) => {
if (!res) {
return;
}
if (res.data.code === 200) {
resolve(res.data);
} else {
reject(res.data);
}
hideLoading();
})
.catch((error) => {
// eslint-disable-next-line prefer-promise-reject-errors
reject({
message: error.msg,
code: error.code,
...error.data,
});
hideLoading();
});
});
}
公共样式文件添加css
#loading {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.75);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
font-size: 20px;
}