index.js
import { createApp, reactive } from 'vue'
import myLoad from './Loading.vue'
const msg = reactive({
show: false,
title: '加载中...'
})
const $loading = createApp(myLoad, { msg }).mount(document.createElement('div'))
// console.log($loading);
const load = {
show (title) { // 控制显示loading的方法
msg.show = true
msg.title = title || '加载中'
document.body.appendChild($loading.$el)
},
hide () { // 控制loading隐藏的方法
msg.show = false
}
}
export default {
install (app) {
app.config.globalProperties.$loading = load
}
}
loading.vue
<template>
<div
class="loading-box"
v-show="msg.show"
>
<div
class="loading-mask"
v-show="!msg.ismask"
></div>
<div class="loading-content">
<div class="animate">
</div>
<div class="text">{{msg.title}}</div>
</div>
</div>
</template>
<script>
export default {
props: {
msg: Object,
}
}
</script>
<style scoped>
.loading-box {
position: relative;
text-align: center;
}
.loading-mask {
position: fixed;
background: #000;
opacity: 0.4;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
}
.loading-content {
position: fixed;
left: 50%;
top: 50%;
width: 1.6rem;
min-height: 1.2rem;
transform: translate(-50%, -50%);
padding: 0.1rem;
background: hsla(0, 0%, 7%, 0.7);
text-align: center;
border-radius: 5px;
color: #fff;
z-index: 5001;
}
.loading-content .animate {
width: 0.4rem;
height: 0.4rem;
vertical-align: baseline;
display: inline-block;
margin: 0 0 0.1rem;
vertical-align: middle;
animation: superLoading 1s steps(12, end) infinite;
background: transparent
url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=')
no-repeat;
background-size: 100%;
}
.loading-content .text {
margin: 0 0 15px;
font-size: 16px;
}
@keyframes superLoading {
0% {
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
transform: rotate3d(0, 0, 1, 360deg);
}
}
@keyframes superLoading {
0% {
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
transform: rotate3d(0, 0, 1, 360deg);
}
}
</style>
main.js
import Loading from './components/loading'
const app = createApp(App);
app.use(router).use(Loading).mount('#app')
页面使用
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
instance.proxy.$loading.show();
instance.proxy.$loading.hide();