vue项目,用的框架是elementUI,现在要在项目的所有页面中加上loading,请求用的是axios,且进行了封装,查了一下记录,特此记录一下亲测可用,欢迎大家一起交流
实现原理:设置一个计数,开始调用为0,展示正在加载中,多个接口一起调用,累加,调用一个接口完成减1,当减到0时,完成最后一个接口调用,关闭正在加载中遮罩。
因为我是把axios封装在一个api.js里面,所以我是在api.js里面写的代码
代码如下:
import axios from 'axios'; import Vue from 'vue' import { Message, Loading } from 'element-ui'; import _ from 'lodash'; // loading框设置局部刷新,且所有请求完成后关闭loading框 let loadingInstance; //loading 实例 let needLoadingRequestCount = 0; //当前正在请求的数量 function showLoading() { let main = document.querySelector('#app') //获取dom节点 if (main) { if (needLoadingRequestCount === 0 && !loadingInstance) { loadingInstance = Loading.service({ target: main, text: '正在加载...', background: 'rgba(0,0,0,0.6)', spinner: 'el-icon-loading' }); } needLoadingRequestCount++; } // console.log('111111111',needLoadingRequestCount) } function closeLoading() { Vue.nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭 needLoadingRequestCount--; needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); // 保证大于等于0 if (needLoadingRequestCount === 0) { if (loadingInstance) { hideLoading() } } // console.log('22222222222',needLoadingRequestCount) }); } //防抖 var hideLoading = _.debounce(() => { loadingInstance.close(); loadingInstance = null; },10); //http request 拦截器 axios.interceptors.request.use( config => { showLoading()// 这里需要注意,必须return config才能生效 return config; }, error => { closeLoading() return Promise.reject(err); } ); //http response 拦截器 axios.interceptors.response.use( response => { closeLoading()return response; }, error => { closeLoading() return Promise.reject(error) } )