新建js文件
/**
* 全局loading效果:合并多次loading请求,避免重复请求
* 当调用一次showLoading,则次数+1;当次数为0时,则显示loading
* 当调用一次hideLoading,则次数-1; 当次数为0时,则结束loading
*/
import { ElLoading } from 'element-plus';
// 定义一个请求次数的变量,用来记录当前页面总共请求的次数
let loadingRequestCount = 0;
// 初始化loading
let loadingInstance;
// 编写一个显示loading的函数 并且记录请求次数 ++
const showLoading = (target) => {
if (loadingRequestCount === 0) {
// element的服务方式 target 我这边取的是表格class
// 类似整个表格loading和在表格配置v-loading一样的效果,这么做是全局实现了,不用每个页面单独去v-loading
loadingInstance = ElLoading.service({ target ,text: '加载中...' ,background: 'rgba(0, 0, 0, 0.8)'});
}
//解决弹窗打开时loading样式被覆盖问题
let div = document.querySelector(".el-loading-mask");
div.style.zIndex ="9999";
loadingRequestCount++
}
// 编写一个隐藏loading的函数,并且记录请求次数 --
const hideLoading = () => {
if (loadingRequestCount <= 0) return
loadingRequestCount--
if (loadingRequestCount === 0) {
loadingInstance.close();
}
}
export {
showLoading,
hideLoading
}
在main.js方法引入文件
// 注入全局方法
import { showLoading, hideLoading } from '@/views/component/loading'
app.config.globalProperties.$showLoading = showLoading
app.config.globalProperties.$hideLoading = hideLoading
还需引入关闭loading的样式放到拦截器中,请求结束关闭
http.js包含拦截器和请求封装
代码如下
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { getToken, removeToken } from '@/utils/token.js';
import Router from '@/router';
import { hideLoading } from '@/views/component/loading'
import qs from 'qs';
//请求拦截器
axios.interceptors.request.use(
(config) => {
config.headers['token'] = getToken();
return config;
},
(err) => {
closeLoading()
ElMessage.error('系统错误,请求失败!');
}
);
//响应拦截器
axios.interceptors.response.use(
(data) => {
closeLoading()
if (data.headers.tokenstatus === 'tokenTimeout') {
removeToken();
ElMessage.error('登录信息已过期,请重新登录!');
Router.push('/login').catch((err) => err);
return data;
}
return data;
},
(err) => {
closeLoading()
switch (err.response.status) {
case 401:
removeToken();
ElMessage.error(err.response.data.body.msg);
Router.push('/login');
break;
default:
ElMessage.error('系统错误,请求失败!');
break;
}
if (!err.response.status) {
closeLoading()
return { data: err.response };
}
}
);
/**
* axios请求的封装
* axios默认请求类型为application/json
*/
axios.defaults.baseURL = '/api/';
// 允许跨域携带cookie信息
axios.defaults.withCredentials = true;
// 表示所有axios请求都是跨域请求,那么每次请求之前都会发送一个Options(预检)请求,用于询问后端是否允许本次请求。所以需要后端也进行相应的设置。
axios.defaults.crossDomain = true;
// post请求
export const postRequest = (url, params, isList = false) => {
params = notNull(params);
let transformRequest = [
function (data) {
let ret = '';
for (let i in data) {
ret += encodeURIComponent(i) + '=' + encodeURIComponent(data[i]) + '&';
}
return ret;
},
];
if (isList) {
transformRequest = [
function (data) {
// 解决传递数组变成对象的问题
return qs.stringify(data, { arrayFormat: 'indices', allowDots: true });
},
];
}
return axios({
method: 'post',
url: url,
data: params,
//axios自带的数据操作方法,可以在请求前将数据格式化
transformRequest: transformRequest,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
});
};
// get请求
export const getRequest = (url, params) => {
return axios({
method: 'get',
url: url,
params: params,
});
};
// 后台返回流的请求
export const postStreamRequest = (url, params) => {
return axios({
method: 'post',
url: url,
params: params,
responseType: 'arraybuffer',
});
};
export const notNull = (data) => {
for (let k1 in data) {
if (data[k1] === null) {
data[k1] = '';
continue;
}
if (Object.prototype.toString.call(data[k1]) === '[object Object]') {
notNull(data[k1]);
continue;
}
if (Array.isArray(data[k1])) {
for (let k2 in data[k1]) {
if (
Object.prototype.toString.call(data[k1][k2]) === '[object Object]'
) {
notNull(data[k1][k2]);
}
}
continue;
}
}
return Object.assign({}, data);
};
function closeLoading(){
try{
hideLoading()
}catch(e){
}
}
使用示例
async function loadZyzhzdjkftjOptionList() {
//请求前使用
proxy.$showLoading()
const { data: res } = await proxy.$postRequest(
"接口"
);
if (res.status == 200) {
//请求成功后隐藏
} else {
proxy.$message.error(res.msg);
}
}