--- description: module | plugins 模块、插件 globs: --- # 模块/插件开发 ## 目录结构 在 `src/modules` 或 `src/plugins` 下添加一个目录 `demo`: ```js demo ├──pages // 页面路由 ├──views // 视图路由 ├──hooks // 常用函数 ├──components // 常用组件 ├──directives // 指令 ├──static // 静态文件目录 ├──store // 状态管理 ├──... // 其他自定义文件 ├──config.ts // 配置文件 └──index.ts // 入口文件 ``` ::: warning 约定的目录名称不可修改,但可自行添加或者删除。 ::: ## pages、views 1. 页面参与权限控制,所以不主动注册目录下的路由,通过 `菜单列表` 中配置注册。或者在 `config.ts` 中手动配置: ```js import { type ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { views: [ { path: "/demo", meta: { label: "测试", }, component: () => import("./views/demo.vue"), }, ], pages: [ { path: "/demo2", meta: { label: "测试", }, component: () => import("./pages/demo.vue"), }, ], }; }; ``` 2. 使页面参与路由缓存,配置 `name` 参数 :::warning `path` 与 `name` 的匹配规则: - /demo/t1 = demo-t1 - /demo/t1-det = demo-t1-det ::: 方式 1: ```html ``` 方式 2: ```html ``` ## components 目录下的组件,全局注册配置方法如下: ```js import { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { components: [ import("./components/demo.vue"), import("./components/demo1.vue"), ], }; }; ``` ## directives `directives` 会以目录下的文件名分别注册指令 ```ts // demo/directives/test.ts export default { created(el, binding) {}, mounted() {}, ... }; ``` 使用 ```html
``` ## store 使用 `pinia` 的推荐写法: ```ts import { defineStore } from "pinia"; import { ref } from "vue"; export const useTestStore = defineStore("test", function () { const count = ref(0); function add() { count.value += 1; } return { count, add, }; }); ``` 使用 ```ts import { useTestStore } from "/$/demo/store"; const test = useTestStore(); test.add(); console.log(test.count); // 1 ``` ::: tip 参考 `base` 模块下 `store` 的导出方式 ::: ## config.ts 模块的配置,程序运行时会读取该文件。 - 全局组件、路由的导入 - 事件钩子 输入 `module-config` 关键字,`vscode` 中会自动生成: ```ts import { ModuleConfig } from "/@/cool"; import { Vue } from "vue"; export default (): ModuleConfig => { return { // 是否启用 enable: true, // 插件名称 label: "插件名称", // 插件描述 description: "插件描述", // 作者 author: "作者", version: "1.0.0", updateTime: "2024-02-02", logo: "", // 忽略 ignore: { // 忽略进度条的请求 NProgress: [ "/base/open/eps", "/base/comm/person", "/base/comm/permmenu", "/base/comm/upload", "/base/comm/uploadMode", ], // 忽略 token 的路由 token: ["/login", "/401", "/403", "/404", "/500", "/502"], }, // 排序 order: 0, // 配置参数 options: { name: "神仙", }, // 示例页面 demo: [ { name: "基础用法", component: () => import("..."), }, ], // 注册全局组件 components: [], // 视图路由 views: [], // 页面路由 pages: [], // 顶部工具栏 toolbar: { order: 1, pc: true, // 是否在 pc 端显示 h5: true, // 是否在 h5 端显示 component: import("./components/index.vue"), }, // 注入全局组件 index: { component: import("./components/index.vue"), }, // 安装时触发 install(app: Vue) {}, // 加载时触发 onLoad(events) {}, }; }; ``` - order 模块加载顺序,值越大越先 - options 提供给外部使用的参数配置: ```ts import { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { options: { // 尺寸 size: 120, // 显示文案 text: "选择文件", // 限制 limit: { // 上传最大数量 upload: 9, // 文件空间选择数 select: 9, // 上传大小限制 size: 100, }, }, }; }; ``` 获取方式: ```ts import { module } from "/@/cool"; const config = module.config("模块名"); ``` - components 提供全局的组件: ```ts import type { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { components: [import("./components/test.vue")], }; }; ``` 批量导入可以使用 [import.meta.glob](mdc:https:/vitejs.dev/guide/features.html#glob-import) 方法: ```ts import { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { components: Object.values(import.meta.glob("./components/**/*")), }; }; ``` - views 全局注册的视图路由,存放在 `/` 中的子路由 `children`: ```ts import { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { views: [ { path: "/test", meta: { label: "测试中心", }, component: () => import("./views/test.vue"), }, ], }; }; ``` - pages 全局注册的页面路由: ```ts import { ModuleConfig } from "/@/cool"; export default (): ModuleConfig => { return { pages: [ { path: "/test", meta: { label: "测试中心", }, component: () => import("./views/test.vue"), }, ], }; }; ``` - install 模块安装时触发。用于预先处理: ```ts import { ModuleConfig } from "/@/cool"; import { Vue } from "vue"; export default (): ModuleConfig => { return { install(app: Vue) { // 注册组件 app.component("test", Test); // 注册指令 app.directive("focus", { created(el, bind) {}, }); }, }; }; ``` - onLoad 模块安装时触发,预先加载数据,如菜单配置、用户信息: 1. 使用 `await` 等待加载完成后往下执行 2. 可往下模块导出某个方法和变量,如 `hasToken` 验证是否有登陆 ```ts import { ModuleConfig } from "/@/cool"; import { Vue } from "vue"; export default (): ModuleConfig => { return { async onLoad() { const { user, menu } = useStore(); if (user.token) { // 获取用户信息 user.get(); // 获取菜单权限 await menu.get(); } return { async hasToken(cb: () => Promise