Files
portal-mini-front/.codebuddy/rules/04-ui-and-permission.md
T
2026-10-25 23:14:53 +08:00

44 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: Element Plus 使用规范、权限控制与 Pinia 状态管理约定
globs: ["src/**/*.{vue,ts}", "src/styles/**/*.scss", "src/router/**/*.ts", "src/store/**/*.ts", "src/directives/**/*.ts"]
---
# UI、权限与状态管理
## Element Plus
1. 组件与图标通过 `unplugin-vue-components` / `unplugin-auto-import` **按需自动导入**;必须手动补充的(如 `ElMessage`、`ElMessageBox`、`ElLoading`)在 `src/types/element-plus.d.ts` 声明,禁止全量 `import ElementPlus from 'element-plus'`。
2. 消息提示统一使用 `ElMessage` / `ElMessageBox` / `ElNotification`,**禁止 `alert` / `confirm` 原生弹窗**。
- 成功 `ElMessage.success`,失败由拦截器统一处理,删除确认用 `ElMessageBox.confirm`。
- 同一操作不要堆叠多条 message。
3. 全局默认配置(size、zIndex、中文语言包)在 `main.ts` 或 `App.vue` 的 `ElConfigProvider` 中统一设置,不在每个组件重复传 `size`。
4. 表单统一 `label-width` 与布局:搜索栏 `inline`,弹窗表单 `label-position="right"`,标签宽度按项目约定(默认 `100px`)。
5. 表格空数据、图片加载失败等边界状态必须处理(`empty-text`、默认头像)。
6. 主题定制通过 `src/styles/element/index.scss` 覆盖 SCSS 变量,**禁止用 `!important` 打补丁**;确需覆盖内部样式时用 `:deep()` 且限定作用域。
## 权限
1. 采用「动态路由 + 按钮级权限」双层控制:
- 菜单/页面:后端返回路由表,前端 `router/index.ts` 中动态 `addRoute`,静态路由仅保留登录、404、首页。
- 按钮:`v-hasPerm="['sys:user:add']"` 指令,指令实现从用户 store 读取权限集合,无权限时**移除 DOM 节点**而非仅禁用。
2. 路由元信息 `meta` 字段固定:`title`、`icon`、`hidden`、`roles`、`keepAlive`、`breadcrumb`。
3. 路由守卫必须处理:已登录访问登录页跳转首页、无 Token 跳登录并携带 `redirect`、路由不存在跳 404。
4. 权限判断不得散落在业务代码里写字符串比较,统一走指令或 store 中的 `hasPermission()`。
## Pinia
1. 一律使用 **setup store** 语法:
```ts
export const useUserStore = defineStore('user', () => {
const token = ref('')
const permissions = ref<string[]>([])
function resetToken() { token.value = '' }
return { token, permissions, resetToken }
}, { persist: true })
```
2. 一个业务域一个 store,放 `src/store/modules/{module}.ts`,index 统一导出。
3. 需要持久化的字段(token、主题、标签栏)必须显式声明 `persist` 路径,**禁止整个 store 无脑持久化**,敏感信息不落 localStorage。
4. 组件内不得直接修改其他模块的 store 状态,需通过该 store 暴露的 action。
5. 接口请求优先放 API 层;store 只做状态存放与跨组件共享,不承载大量业务过程。
## 路由与页面缓存
- 页面组件 `name` 必须与路由 `name` 一致,否则 `<keep-alive>` 的 `include/exclude` 失效。
- 列表页默认开启缓存;从详情页返回时保留查询条件,从菜单进入时重置。