功能分析
vue项目中所有的请求一般都是通过axios,所以我们需要给axios新增请求和响应拦截,在请求拦截中显示loading,和响应拦截中关闭loading。
所以我们需要定义两个全局方法,一个是显示loading,叫 s h o w L o a d i n g ( ) , 另 一 个 叫 showLoading(),另一个叫 showLoading(),另一个叫hideLoading()关闭全屏loading。
代码实现
上面的梳理,我们明确了,需要定义两个全局方法,一个显示loading一个关闭loading,这里我们定义一个Vue的插件通过插件动态给实例安装 显示和关闭Loading方法。
定义$loading插件,在Vue构造函数原型上添加两个方法
以下loading.js代码
const $loading = {
install: (Vue) => {
// 添加 显示loading方法
Vue.prototype.$showLoading = () => {
console.log('loading显示')
}
// 添加关闭loading方法
Vue.prototype.$hideLoading = () => {
console.log('loading关闭')
}
}
}
export default $loading;
// 使用时,在main.js入口函数中引入,使用插件即可安装
Vue.use($loading)
添加axios请求和相应拦截,调用显示和关闭loading方法
import Vue from 'vue';
// 定义Vue实例 调用全局显示和关闭loading方法
const vm = new Vue();
// 请求拦截
axios.interceptors.request.use(function(config) {
// 调用loading方法
vm.$showLoading()
return config
}, function(error) {
// 在请求出错调用 关闭loading方法
vm.$hideLoading()
return Promise.reject(error)
})
// 相应拦截
axios.interceptors.response.use(function(response) {
vm.$hideLoading()
return response
}, function(error) {
vm.$hideLoading()
return Promise.reject(error)
})
当然我们 在数据请求不是打印,而是 显示loading,数据过来时应该关闭loading,所以接下来我们实现这两个效果
通过单文件组件 定义显示loading结构
我们目前的问题是,在显示loading时不是打印而是要显示全局loading的html结构,在关闭loading时要隐藏!
为了实现这个需求,我们通过vue的单文件组件来定义loading的html结构和控制loading显示隐藏
loading.vue
<template>
// mask是loading的背景 v-show控制loading显示或消失
<div class="mask" v-show="isShow"></div>
<div class="loading"></div>
</template>
<script>
export default {
return {
isShow: false // 默认不显示
}
}
</script>
<style lang="scss">
// 定义动画 控制loading旋转
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .7);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
.loading {
width: 30px;
height: 30px;
border: 6px solid rgb(219, 140, 13);
border-radius: 21px;
border-left-color: transparent;
animation: rotate 500ms infinite;
}
}
</style>
loading.js中获取单文件组件 html结构 并在 s h o w L o a d i n g 方 法 调 用 时 显 示 , 在 showLoading方法调用时显示,在 showLoading方法调用时显示,在hideLoading时隐藏
// loading.js中
import LoadingVue from './loading.vue';
const $loading = {
install: (Vue) => {
// 通过Vue.extend方法 获取LoadingComponent 组件类
const LoadingComponent = Vue.extend(LoadingVue);
// new LoadingComponent得到组件的实例
const vm = new LoadingComponent();
// 获取组件实例的html 并插入到body中
const tpl = vm.$mount().$el;
// 插入到body中
document.body.appendChild(tpl);
// 添加 显示loading方法
Vue.prototype.$showLoading = () => {
// 通过改变实例 .mask v-show绑定变量控制显示
vm.isShow = true
}
// 添加关闭loading方法
Vue.prototype.$hideLoading = () => {
// 通过改变实例 .mask v-show绑定变量控制隐藏
vm.isShow = false
}
}
}
最后在main.js中使用插件 在axios拦截器中控制显示隐藏就ok啦!!
// main.js
import Vue from 'vue';
import loading from './plugins/loading';
Vue.use(loading)
axios 拦截器中使用
import Vue from 'vue';
const vm = new Vue();
axios.interceptors.request.use(config => {
vm.$showLoaing()
return config
}, error => {
vm.$hideLoading()
return Promise.reject(error)
})
// 响应拦截
axios.interceptors.response.use(config => {
vm.$hideLoading()
return response
}, error => {
vm.$hideLoading()
return Promise.reject(error)
})