本文记录 Vue3 + ts 实现自定义一个全局插件,用于进行 message 消息提示,所谓全局插件即挂载到 vue 实例上,在 App 的任一子组件中均可通过 app 的实例调用该方法。消息提示功能只是示例主要是记录 Vue3 自定义插件功能的写法。
文件结构:
src/components/Toast/index.vue 文件用于搭建和渲染消息在页面上的显示效果,比如需要显示在页面的哪个位置、字体、颜色、显示和隐藏的动画效果等;
src/components/Toast/index.ts 文件用于实现将消息的显示/隐藏等方法全局挂载到 app 实例上(注:对象写法默认需要导出一个 install() 方法),这样在 main.ts 中导入并注册该组件即可;
主要代码
index.vue 文件
<!-- 封装消息提示插件 -->
<template><Transition enter-active-class="animate__animated animate__bounceInRight"leave-active-class="animate__animated animate__bounceOutRight"><div v-if="isShow" class="message">{{ tipText }}</div></Transition>
</template><script setup lang='ts'>
import { ref, reactive } from 'vue';
let isShow = ref<boolean>(false)
let tipText = ref<string | number>('默认提示内容')
const show = (str: string | number, time: number = 3000) => {tipText.value = strisShow.value = true// 2 秒后自动关闭setTimeout(() => {isShow.value = false}, time);
}
const hide = () => isShow.value = false
// 将组件内部的方法导出,方便外部访问
defineExpose({show,hide
})
</script><style lang='less' scoped>
.message {height: 40px;line-height: 40px;padding: 0 20px;border-radius: 5px;background-color: rgba(200, 217, 217, 0.5);position: fixed;top: 50px;right: 100px;
}
</style>
index.ts 文件
import { App, createVNode, VNode, render } from 'vue'
import Toast from './index.vue'export default {install(app: App) {// 将组件转换为虚拟DOMconst Vnode: VNode = createVNode(Toast)// 将虚拟DOM挂载到页面节点上render(Vnode, document.body)// 将插件的主要方法挂载到 app.config.globalProperties 上,这里的 $toast 是自定义的app.config.globalProperties.$toast = {// 这里仅挂载了一个 show 方法到 $toast 上show(str: string | number, time?: number) {Vnode.component?.exposed?.show(str, time)},}},
}
然后在 main.ts 中导入并注册该插件
// 注册插件
import Toast from './components/Toast'
const app = createApp(App)// 只要是插件都需要进行注册,都是通过 app.use() 进行注册的
app.use(Toast)
使用插件
进行到此我们的自定义插件就已经可以在任意 App 的子组件中使用了,如:
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
// 使用自定义的全局消息提示插件
instance?.proxy?.$toast.show('this is default message')
效果图
扩充声明文件
注:以上虽然全局的消息插件是能使用了,但是因为 $toast 缺乏类型声明文件所以会报错而且其内部的方法、变量等成员均没有智能提示,所以我们还需要在 main.ts 文件中对 $toast 的成员类型进行声明:将 main.ts 文件中关于注册该自定义插件的代码进行如下更新:
// 注册插件
import Toast from './components/Toast'
const app = createApp(App)type Toast = {show: <T>(str: string | number, time?: number) => void
}
// 编写自定义插件的声明文件,防止报错,声明后也会有智能提示
declare module '@vue/runtime-core' {export interface ComponentCustomProperties {$toast: Toast}
}// 只要是插件都需要进行注册,都是通过 app.use() 进行注册的
app.use(Toast)
注:更新后如果页面中还是报错(爆红色提醒),重启服务即可,且在页面上访问 $toast 的内部成员也会有智能提示,比如 show() 方法,且该方法需要几个参数、参数需要什么类型都会有提示。至此我们 Vue3 + ts 的自定义插件就封装完成啦!