插件编写
插件需要暴露一个对象或函数,并通过app.use注册到全局,省略注册过程。
Loading/index.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import type { App, VNode } from "vue" import { createVNode,render } from "vue" import Loading from "./index.vue"
export default { install(app: App) { const VNode:VNode = createVNode(Loading) render(VNode,document.body) VNode.component?.exposed app.config.globalProperties.__loading = { show: VNode.component?.exposed?.show, hide: VNode.component?.exposed?.hide, isShow: VNode.component?.exposed?.isShow } } }
|
Loading/index.vue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div v-if="isShow" class="loading"> <div class="loading-content">Loading...</div> </div> </template>
<script setup lang="ts"> const isShow = ref<boolean>(false)
const show = ()=> isShow.value = true const hide = ()=> isShow.value = false
defineExpose({show,hide,isShow}) </script>
<style scoped lang="scss"> .loading { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center;
&-content { font-size: 30px; color: #fff; } } </style>
|
App.vue:
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div></div> </template>
<script setup lang="ts"> const instance = getCurrentInstance() instance?.proxy?.__loading.show()
setTimeout(() => { instance?.proxy?.__loading.hide() }, 5000) </script>
|
源码
手写一个myUse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import type { App } from "vue" import { app } from "./main"
interface Use { install:(app:App,...options:any[])=>void }
const installList = new Set()
export function MyUse<T extends Use>(plugin:T,...options:any[]) { if(installList.has(plugin)) { console.error("already regist!",plugin) } else { plugin.install(app,...options) installList.add(plugin) } }
|
在Vue源码(/package/runtime-core/src/apiCreateApp.ts
)中可以看到use的源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const installedPlugins = new Set()
use(plugin: Plugin, ...options: any[]) { if (installedPlugins.has(plugin)) { __DEV__ && warn(`Plugin has already been applied to target app.`) } else if (plugin && isFunction(plugin.install)) { installedPlugins.add(plugin) plugin.install(app, ...options) } else if (isFunction(plugin)) { installedPlugins.add(plugin) plugin(app, ...options) } else if (__DEV__) { warn( `A plugin must either be a function or an object with an "install" ` + `function.` ) } return app },
|