场景:我们在项目中会调用很多后台接口,但是有一些请求时间过长的接口需要一个过渡状态展示给客户,我们通常会给点击的那个按钮去设置一个loading或者disabled状态,所以我们可以在axios的请求拦截器和返回拦截器中直接设置全局loading状态
loading插件代码如下:
//loading.js
/*
* 可以自己找不同的loading图传入组件
* imagePath在main.js注册时候传入的loading动图
* 如:'./static/image/loading.gif'
* */
const install = ( Vue, imagePath ) => {
Vue.$loading = Vue.prototype.$loading = {
//loading状态显示方法
show(){
let loadingBox = document.getElementById('loading-box');
//先判断是否有遮罩层,如果有直接插入loading图,没有则先插入遮罩层
if (loadingBox) {
loadingBox.style.display = 'flex';
loadingBox.innerHTML = `
<img src=${ imagePath } alt="">
`;
} else {
let box = document.createElement('div');
box.id = 'loading-box';
document.getElementById('app').appendChild(box);
loadingBox = document.getElementById('loading-box');
if (loadingBox) {
loadingBox.style.display = 'flex';
loadingBox.innerHTML = `
<img src=${ imagePath } alt="">
`;
}
}
},
//loading状态隐藏方法
hide(){
let loadingBox = document.getElementById('loading-box');
if (loadingBox) {
loadingBox.parentNode.removeChild(loadingBox);
}
}
};
};
/*
* 注:对外暴露的函数名必须为install,当用Vue.use全局引用注册的时候会默认调用install方法
* 也可以写成
* const Loading = {
* install: (Vue, imagePath)=>{
* Vue.$loading = Vue.prototype.$loading = {
* //......
* }
* }
* };
* export default {
* Loading
* }
* */
export default {
install
}
写好插件方法后需要在main.js项目的入口文件中进行引入和注册,代码如下:
const myLoading = require('vue-axios-loading');
//loading图存储目录,依据打包后dist文件夹层级结构设置相对路径
const src = './static/image/loading.gif';
Vue.use(myLoading, src);
最后在main.css主样式表里设置loading遮罩层的样式,代码如下:
#loading-box {
display: flex;
justify-content: center;
align-items: center;
z-index: 99999;
position: absolute;
top: 0;
background-color: rgba(0,0,0,0.2);
height: 100%;
width: 100%;
}
这里用了最简单的flex布局居中,如果项目中不使用flex布局,大家也可以自己写居中样式
最后调用,如果在组件中调用我们可以直接使用this.$loading.show()
和this.$loading.hide()
进行调用,因为在组件中this
指向默认为Vue
实例本身,但是如果在axios
拦截器中使用时需要先对Vue进行引入,然后new出一个实例,代码如下:
import Vue from 'vue'
const vm = new Vue();
//拦截器调用方法及位置
//在请求拦截器中开启loading
axios.interceptors.request.use(
response => {
//......项目业务处理代码
vm.$loading.show();
return response
},
err => {
return Promise.reject(err)
}
);
//响应拦截器中关闭loading
axios.interceptors.response.use(
config => {
//......项目业务处理代码
vm.$loading.hide();
return config
},
err => {
//......项目业务处理代码
vm.$loading.hide();
return Promise.reject(err)
}
);
附带一个loading图:
最后给大家分享两个免费的loading图下载地址: