原理:设置一个计数,开始调用为0,展示正在加载中,多个接口一起调用,累加,调用一个接口完成减1,当减到0时,完成最后一个接口调用,关闭正在加载中遮罩。
代码实现如下:
import { Message, Loading } from 'element-ui';
import _ from 'lodash';
let loadingInstance; //loading 实例
let needLoadingRequestCount = 0; //当前正在请求的数量
function showLoading() {
let main = document.querySelector('#elMain')
if (main) {
if (needLoadingRequestCount === 0 && !loadingInstance) {
loadingInstance = Loading.service({
target: main, text: '正在加载...', background: 'rgba(0,0,0,0.3)'
});
}
needLoadingRequestCount++;
}
}
function closeLoading() {
Vue.nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
needLoadingRequestCount--;
needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); // 保证大于等于0
if (needLoadingRequestCount === 0) {
if (loadingInstance) {
hideLoading()
}
}
});
}
//防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
//因为有时会碰到在一次请求完毕后又立刻又发起一个新的请求的情况(比如删除一个表格一行后立刻进行刷新)
//这种情况会造成连续 loading 两次,并且中间有一次极短的闪烁。通过防抖可以让 300ms 间隔内的 loading 便合并为一次,避免闪烁的情况。
var hideLoading = _.debounce(() => {
loadingInstance.close();
loadingInstance = null;
}, 300);
axiosHttp.interceptors.request.use(config => { // request拦截器
showLoading()
return config
}, err => {
closeLoading()
return Promise.reject(err);
})
axiosHttp.interceptors.response.use(
response => {
closeLoading()
},
error => {
closeLoading()
}