一、示例效果
封装一个loading效果,通过函数去调用
加载时创建DOM,加载完删除DOM
二、Loading的封装
1. components/Loading/index.vue
js
<template>
<div class="loader">
<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>
</div>
</template>
<style lang="less" scoped>
.loader {
background: rgba(0, 0, 0, 0.2);
bottom: 0;
left: 0;
overflow: hidden;
position: fixed;
right: 0;
top: 0;
z-index: 99999;
}
.loader-inner {
bottom: 0;
height: 60px;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 100px;
}
.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);
}
}
</style>
2. components/Loading/index.js
js
import Vue from "vue";
import LoadingUI from "./index.vue";
const instance = () => {
const JSloading = Vue.extend(LoadingUI);
const loadingVm = new JSloading().$mount();
return {
show() {
document.body.appendChild(loadingVm.$el);
},
hide() {
loadingVm.$el.remove();
}
}
}
export default instance()
三、使用
1. 单文件引入使用
js
import loading from "@/components/Loading";
async getList() {
try {
loading.show();
const res = await listApi1();
console.log(res);
} catch (err) {
console.log(err);
} finally {
loading.hide();
}
}
2. 或者在main.js中进行全局注册
main.js
js
import loading from "@/components/Loading";
Vue.prototype.$loading = loading
使用时不需要引入,直接通过this调用
js
async getList() {
try {
this.$loading.show();
const res = await listApi1();
console.log(res);
} catch (err) {
console.log(err);
} finally {
this.$loading.hide();
}
}
3. 也可以在axios拦截器中,给所有的接口都添加上loading
js
import axios from 'axios'
import loading from "@/components/Loading";
const service = axios.create()
// request 拦截器
service.interceptors.request.use(
config => {
loading.show()
return config
},
error => {
loading.hide()
return Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
response => {
loading.hide()
return response.data.data
},
error => {
loading.hide()
return Promise.reject(error)
}
)
export default service