1. 在components中新建loading文件夹
index.vue代码:
<template>
<div v-if="isShow" class="loading_container">
<div class="loader">
<div class="outer"></div>
<div class="middle"></div>
<div class="inner"></div>
<div class="loading">加载中<span class="load"></span></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const isShow = ref<boolean>(false);
const show = () => (isShow.value = true);
const hide = () => (isShow.value = false);
defineExpose({
show,
hide,
isShow,
});
</script>
<style scoped lang="less">
.loading_container {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.loader {
position: relative;
.loading {
margin-top: 6em;
color: #3cefff;
letter-spacing: 5px;
.load {
height: 2px;
width: 2px;
display: inline-block;
/*box-shadow: 2px 0 0 white ,7px 0 0 white, 12px 0 0 white;*/
animation: change 2.4s infinite steps(1, start);
}
@keyframes change {
25% {
box-shadow: 2px 0 0 #3cefff;
}
50% {
box-shadow: 2px 0 0 #3cefff, 7px 0 0 #3cefff;
}
75% {
box-shadow: 2px 0 0 #3cefff, 7px 0 0 #3cefff, 12px 0 0 #3cefff;
}
}
}
}
.outer,
.middle,
.inner {
border: 3px solid transparent;
border-top-color: #3cefff;
border-right-color: #3cefff;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
}
.outer {
width: 3.5em;
height: 3.5em;
margin-left: -1.75em;
margin-top: -1.75em;
animation: spin 2s linear infinite;
}
.middle {
width: 2.1em;
height: 2.1em;
margin-left: -1.05em;
margin-top: -1.05em;
animation: spin 1.75s linear reverse infinite;
}
.inner {
width: 0.8em;
height: 0.8em;
margin-left: -0.4em;
margin-top: -0.4em;
animation: spin 1.5s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
index.ts代码:
import type { App, VNode } from 'vue'
import Loading from './index.vue'
import { createVNode, render } from 'vue';
export default {
install(app: App) {
const Vnode: VNode = createVNode(Loading)
render(Vnode, document.body)
app.config.globalProperties._loading = {
show: Vnode.component?.exposed?.show,
hide: Vnode.component?.exposed?.hide
}
}
}
2. 在main.ts中引入Loading并挂载到vue上
import { createApp } from 'vue'
import App from './App.vue'
import Loading from './components/Loading'
const app = createApp(App)
app.use(Loading)
app.mount('#app')
3. 在组件中调用show和hide方法控制loading显示与隐藏
<script setup lang="ts">
import { getCurrentInstance } from "vue";
const instance = getCurrentInstance() as any;
const loading = () => {
instance?.proxy._loading.show();
setTimeout(() => {
instance?.proxy._loading.hide();
}, 3000);
};
</script>