新建两个文件,index.ts将其挂载到body上面,.vue文件是书写样式并把显示和隐藏的方法暴露出来
index.ts的具体代码
import type {App,VNode} from 'vue'
import Loading from './loading.vue'
import { createVNode,render } from 'vue'
export default {
install(app:App){
// 创建VNode
const Vnode:VNode = createVNode(Loading)
// 参数一是挂载的Vnode元素,参数二是挂载到body
render(Vnode,document.body)
// 全局注册$Loading
console.log('first', Vnode.component?.exposed)
app.config.globalProperties.$loading= {
show:Vnode.component?.exposed?.show,
hide:Vnode.component?.exposed?.hide,
}
}
}
index.vue
<template>
<div class="loading" v-if="isShow">
Loading....
</div>
</template>
<script lang='ts' setup>
import { ref, reactive } from "vue";
const isShow = ref<boolean>(false);
const show = () => {
isShow.value = true;
};
const hide = () => {isShow.value = false};
</script>
<style lang='scss' scoped>
.loading {
background-color: #000;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
</style>
挂载到mian.ts
import Loading from '@/views/loading/index'
app.use(Loading)
使用
import { getCurrentInstance } from "vue"
const instance = getCurrentInstance()
instance?.proxy.$loading.show()
解决ts的报错
type Loading = {
show:()=>void,
hide:()=>void,
}
// 声明要扩充@vue/runtime-core包的声明.
// 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.
declare module 'vue' {
export interface ComponentCustomProperties {
$loading: Loading,
}
}