在项目中会出现前端向后端发送请求,而请求的数据比较多的时候,页面会出现空白,假死现象,其实这是对使用功能是没有任何影响的,但是为了更好的用户体验,我们一般会在请求数据和获得后端给的数据这段时间加入以个友好的loading提示,如下图所示。本案例是基于vue2的。
在src的components下创建loading包如下图
index.vue的代码如下:
<template>
<div v-if="show">
<div class="loader-rainbow">
<div class="loader-inner">
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="box10" style="margin-top: 120px">拼命加载中....</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "loading",
props: {
show: Boolean,
},
data() {
return {};
},
};
</script>
<style scoped>
.loader-rainbow {
position: fixed;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
z-index: 9999;
background-color: rgba(0,0,0,.5);
}
.loader-inner {
bottom: 0;
height: 100px;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 150px;
}
.loader-line-wrap {
animation: spin 2000ms cubic-bezier(0.175, 0.885, 0.32, 1.275) infinite;
box-sizing: border-box;
height: 50px;
left: 0;
overflow: hidden;
position: absolute;
top: 0;
transform-origin: 50% 100%;
width: 100px;
}
.loader-line {
border: 4px solid transparent;
border-radius: 100%;
box-sizing: border-box;
height: 100px;
left: 0;
margin: 0 auto;
position: absolute;
right: 0;
top: 0;
width: 100px;
}
.loader-line-wrap:nth-child(1) {
animation-delay: -50ms;
}
.loader-line-wrap:nth-child(2) {
animation-delay: -100ms;
}
.loader-line-wrap:nth-child(3) {
animation-delay: -150ms;
}
.loader-line-wrap:nth-child(4) {
animation-delay: -200ms;
}
.loader-line-wrap:nth-child(5) {
animation-delay: -250ms;
}
.loader-line-wrap:nth-child(1) .loader-line {
border-color: hsl(0, 80%, 60%);
height: 90px;
width: 90px;
top: 7px;
}
.loader-line-wrap:nth-child(2) .loader-line {
border-color: hsl(60, 80%, 60%);
height: 76px;
width: 76px;
top: 14px;
}
.loader-line-wrap:nth-child(3) .loader-line {
border-color: hsl(120, 80%, 60%);
height: 62px;
width: 62px;
top: 21px;
}
.loader-line-wrap:nth-child(4) .loader-line {
border-color: hsl(180, 80%, 60%);
height: 48px;
width: 48px;
top: 28px;
}
.loader-line-wrap:nth-child(5) .loader-line {
border-color: hsl(240, 80%, 60%);
height: 34px;
width: 34px;
top: 35px;
}
@keyframes spin {
0%,
15% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.box10 {
background: linear-gradient(to bottom, rgb(107, 175, 240), rgb(245, 137, 227));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: bold;
font-size: 20px;
}
</style>
index.js的代码如下:
在渲染当前页面时,可能会发送多个请求,loadingNum记录着当前的请求个数,当当前请求的个数等于0个时候就会取消loading。
import Vue from 'vue'
import loading001 from './index.vue'
const LoadingConstructor = Vue.extend(loading001)
let loadingNum=0;
const instance = new LoadingConstructor({
el: document.createElement('div')
})
instance.show = false
const loading = {
show() {
instance.show = true
document.body.appendChild(instance.$el)
loadingNum++
},
hide() {
loadingNum--
if(loadingNum===0){
instance.show = false
}
}
}
export default {
install() {
if (!Vue.$showLoading) {
Vue.$showLoading = loading
}
Vue.mixin({
created() {
this.$showLoading = Vue.$showLoading
}
})
}
}
在前端的拦截器的代码:
// create an axios instance
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
baseURL:baseURL,
timeout: 10000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
Vue.$showLoading.show()
return config
},
err => {
return Promise.reject(err)
}
)
// response interceptor
service.interceptors.response.use(
response => {
const res = response
if (res.status !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
} else {
Vue.$showLoading.hide()
return res.data
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service