Vue 3 插件开发实战:封装全局组件与指令并做 TS 类型增强

test12026-09-219 次阅读

插件解决什么问题

当你把一个 UI 库或一套通用能力(全局弹窗、权限指令、消息提示)复用到多个项目时,逐个在 main.ts 里注册组件和指令既重复又容易遗漏。Vue 3 的 Plugin 机制把 install 逻辑收敛到一个入口,配合 TypeScript 声明合并还能让全局属性获得类型提示。

实现一个 UI 插件

install 接收 app 实例,在内部集中注册组件、指令与全局属性。这样调用方只需 app.use(MyUiPlugin) 一行即可。

import type { App, Plugin } from 'vue';
import BaseModal from './components/BaseModal.vue';
import { permission } from './directives/permission';

export interface MyUiOptions {
  modalZIndex?: number;
}

export const MyUiPlugin: Plugin = {
  install(app: App, options: MyUiOptions = {}) {
    app.component('BaseModal', BaseModal);
    app.directive('permission', permission);
    app.config.globalProperties.$ui = {
      modalZIndex: options.modalZIndex ?? 1000,
    };
  },
};

让全局属性获得类型

Vue 3 没有自动推导 globalProperties 的类型,需要用模块增强把 $ui 声明进 ComponentCustomProperties,否则在模板里使用会报类型错误。

declare module 'vue' {
  interface ComponentCustomProperties {
    $ui: {
      modalZIndex: number;
    };
  }
}

在组件中使用

import { MyUiPlugin } from '@/plugins/my-ui';

createApp(App).use(MyUiPlugin, { modalZIndex: 2000 }).mount('#app');

模板中直接用 <BaseModal />,或给按钮加 v-permission="'user:delete'"。如果组件内部需要读取全局属性,可以用 getCurrentInstance()?.appContext.config.globalProperties.$ui 拿到的就是带类型的对象。

工程建议

  • 插件的副作用尽量收敛在 install 内,避免模块加载即执行。
  • 选项参数通过第二个参数传入,给一个合理的默认值。
  • 涉及全局属性一定要补 declare module 增强,否则 TS 项目会失去提示甚至编译报错。
  • 指令和组件按功能分组,插件只做编排,不写业务逻辑。
T

test1

文章作者

插件解决什么问题 当你把一个 UI 库或一套通用能力(全局弹窗、权限指令、消息提示)复用到多个项目时,逐个在 main...

分类
技术
发布时间
2026-09-21
字数
约 1347 字
阅读
9 次