Loading.vue
<template>
<div class="loading-wrap">
<div v-if="mask" class="mask"></div>
<div class="loading" v-cloak>
<div class="load-cont">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="text">{{ title || "加载中..." }}</div>
</div>
</div>
</template>
<script setup>
defineProps({
title: {
type: String
},
mask: {
type: Boolean
}
})
</script>
<style lang="less" scoped>
.loading-wrap {
.mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 3001;
}
.loading {
width: 250px;
height: 250px;
position: fixed;
left: 50%;
top: 30%;
background-color: rgba(0, 0, 0, 0.7);
transform: translateX(-100px);
border-radius: 10px;
z-index: 3000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.load-cont {
width: 60px;
height: 60px;
position: relative;
.line {
position: absolute;
left: 50%;
top: 0;
width: 4px;
height: 100%;
}
.line::before {
position: absolute;
top: 0;
display: block;
content: '';
width: 4px;
height: 15px;
background-color: white;
border-radius: 5px 5px 0 0;
}
.line::after {
position: absolute;
bottom: 0;
display: block;
content: '';
width: 4px;
height: 15px;
background-color: white;
border-radius: 0 0 5px 5px;
}
.line:nth-child(2) {
transform: rotate(30deg);
}
.line:nth-child(3) {
transform: rotate(60deg);
}
.line:nth-child(4) {
transform: rotate(90deg);
}
.line:nth-child(5) {
transform: rotate(120deg);
}
.line:nth-child(6) {
transform: rotate(150deg);
}
.line:nth-child(1)::before {
animation: loading 1.2s linear 0s infinite;
}
.line:nth-child(2)::before {
animation: loading 1.2s linear 0.1s infinite;
}
.line:nth-child(3)::before {
animation: loading 1.2s linear 0.2s infinite;
}
.line:nth-child(4)::before {
animation: loading 1.2s linear 0.3s infinite;
}
.line:nth-child(5)::before {
animation: loading 1.2s linear 0.4s infinite;
}
.line:nth-child(6)::before {
animation: loading 1.2s linear 0.5s infinite;
}
.line:nth-child(1)::after {
animation: loading 1.2s linear 0.6s infinite;
}
.line:nth-child(2)::after {
animation: loading 1.2s linear 0.7s infinite;
}
.line:nth-child(3)::after {
animation: loading 1.2s linear 0.8s infinite;
}
.line:nth-child(4)::after {
animation: loading 1.2s linear 0.9s infinite;
}
.line:nth-child(5)::after {
animation: loading 1.2s linear 1.0s infinite;
}
.line:nth-child(6)::after {
animation: loading 1.2s linear 1.1s infinite;
}
@keyframes loading {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
.text {
margin-top: 26px;
font-size: 30px;
color: #fff;
}
}
}
</style>
index.js
import { createApp } from 'vue'
import Loading from './Loading.vue'
export default {
instance: null,
parent: document.createElement('div'),
showLoading ({ title = '', mask = false }) {
if (this.instance !== null) this.clear()
this.instance = createApp(Loading, { title, mask })
document.body.appendChild(this.parent)
this.instance.mount(this.parent)
},
hideLoading () {
this.clear()
},
clear () {
if (this.instance !== null) {
this.instance.unmount(this.parent)
document.body.removeChild(this.parent)
this.instance = null
}
},
}
//调用
import utils from './index.js'
utils.showLoading({title:"loading",mask:true})