vue3+ts 自定义Loading组件---Vnode组件

556 阅读1分钟

新建两个文件,index.ts将其挂载到body上面,.vue文件是书写样式并把显示和隐藏的方法暴露出来

image.png

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,
  }
}