初始提交:项目迁移,前端(管理端)
This commit is contained in:
464
cool-admin-vue/.cursor/rules/module.mdc
Normal file
464
cool-admin-vue/.cursor/rules/module.mdc
Normal file
@@ -0,0 +1,464 @@
|
||||
---
|
||||
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
|
||||
<script lang="ts" setup>
|
||||
defineOptions({
|
||||
name: "demo",
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
方式 2:
|
||||
|
||||
```html
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
name: "demo",
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## 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
|
||||
<div v-test></div>
|
||||
```
|
||||
|
||||
## 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<any> | void) {
|
||||
if (user.token) {
|
||||
if (cb) await cb();
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
其他模块中接收 `hasToken` 方法:
|
||||
|
||||
```ts
|
||||
import { ModuleConfig } from "/@/cool";
|
||||
import { useDict } from "./index";
|
||||
|
||||
export default (): ModuleConfig => {
|
||||
return {
|
||||
onLoad({ hasToken }) {
|
||||
const { dict } = useDict();
|
||||
|
||||
hasToken(() => {
|
||||
dict.refresh();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## index.ts
|
||||
|
||||
该模块需要对外开放的变量及方法,方便于别人直接使用:
|
||||
|
||||
```ts
|
||||
// modules/test/index.ts
|
||||
import { useStore } from "./store";
|
||||
|
||||
export function useTest() {
|
||||
return {
|
||||
// 导出 pinia
|
||||
...useStore(),
|
||||
|
||||
// 自定义方法
|
||||
test() {},
|
||||
|
||||
// 自定义变量
|
||||
data: {
|
||||
description: "数据描述",
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
导出命名规则 `useBase` `useDemo` `useDict` use + 模块名
|
||||
|
||||
使用:
|
||||
|
||||
```ts
|
||||
import { useTest } from "/$/test";
|
||||
|
||||
const { data, test } = useTest();
|
||||
```
|
||||
Reference in New Issue
Block a user