每一个Vue插件中都有一个install方法,当使用Vue.use(插件名)时Vue将调用插件中的install方法执行对应功能,下面是一个展示Loading状态的Vue插件
- Loading文件夹
Loading.vue
<template>
<!-- 定义初始状态false -->
<div v-if="show" class="default">
<div class="loading">Loading……</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
let show = ref<boolean>(false)
const hide = () => show.value = false
const emerge = () => show.value = true
// 暴露函数,在vNode中可以通过component.exposed.方法名()来调用
defineExpose({
hide,
emerge,
})
</script>
<style scoped>
.default {
background-color: #ccc;
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
font-size: 50px;
}
.loading {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 300px;
background-color: #928f8f;
}
</style>
index.ts
import type { App, VNode } from 'vue'
// 引入创建函数和render渲染函数
import { createVNode, render } from 'vue'
// 引入组件,但此时组件还不是虚拟DOM,不能直接使用
import LoadingVue from './Loading.vue'
export default {
install(app: App) {
// 创建vNode(虚拟DOM)
const vNode: VNode = createVNode(LoadingVue)
// 将vNode挂载到页面上,此时v-if是false状态
render(vNode, document.body)
// 定义全局变量以便在其他组件中使用
app.config.globalProperties._loading = {
emerge(){
vNode.component?.exposed?.emerge()
},
hide(){
vNode.component?.exposed?.hide()
}
}
},
}
src文件夹:
App.vue
<template>
<button @click="show(true)">显示</button>
<button @click="show(false)">隐藏</button>
</template>
<script setup lang="ts">
import { ref, reactive, getCurrentInstance } from 'vue'
let instance = getCurrentInstance()
const show = (option: boolean) => {
if (option == true) {
// 调用全局方法以展示/隐藏组件
instance?.proxy?._loading.emerge()
} else {
instance?.proxy?._loading.hide()
}
}
</script>
<style></style>
main.ts
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import Loading from './components/Loading'
export const app = createApp(App)
app.use(Loading)
app.mount('#app')
// 以下为声明文件部分
type Lod = {
emerge: () => void
hide : () => void
}
declare module '@vue/runtime-core'{
export interface ComponentCustomProperties{
_loading:Lod
}
}
app.use源码实现:
MyUse
// 手动实现app.use,实际上就是调用install方法并传入app参数
import type { App } from 'vue'
import { app } from './main'
interface plugins {
install: (app: App) => void
}
// 添加缓存策略防止插件被重复注册
const installList = new Set()
// 添加限制,plugin必须实现install方法
export const MyUse = <T extends plugins>(plugin: T) => {
if(installList.has(plugin)){
console.log('此插件已被注册');
}else{
plugin.install(app)
installList.add(plugin)
}
}
接下来在main.ts中引入MyUse,然后使用MyUse(插件名)进行注册即可