12 KiB
12 KiB
中后台前端页面设计规范
基于 itfx-front 项目现有技术栈与实现,整理的一套通用、可直接落地的前端设计规范。
后续开发须遵循本规范,确保视觉与交互一致性。
一、技术栈约定
| 类别 | 技术选型 | 版本/说明 |
|---|---|---|
| 框架 | Vue 3 | 使用 Composition API、<script setup> |
| UI 库 | Arco Design Vue | 主 UI 框架,优先使用 |
| 辅助 UI | Element Plus | 仅在特殊场景使用 |
| 表格 | vxe-table / Handsontable | 见「表格」章节 |
| 构建 | Vite | 6.x |
| 状态 | Pinia | |
| 国际化 | vue-i18n | |
| 样式 | Less + UnoCSS + 全局 CSS 变量 | |
| 路由 | vue-router | 4.x |
二、布局规范
2.1 整体结构
a-layout (垂直)
├── TopNav(顶部导航,fixed)
├── a-layout-content
│ ├── paddingTop: 顶部导航高度 + Tab 栏高度(可选)
│ └── PageLayout(router-view + keep-alive)
└── Footer(可选)
约定:
- 主内容背景色:
#f0f3f4 - 页面容器使用
[class$='-container'],统一padding: 16px - 内容区域使用
overflow: hidden、height: 100%保证高度正确
2.2 页面内容结构
单页内容推荐结构:
<div class="xxx-container" style="background-color: #fff;">
<!-- 1. 页面头部操作区(可选) -->
<div class="page-header">
<a-space>...</a-space>
<a-space>...</a-space>
</div>
<!-- 2. 表格工具栏 -->
<div class="table-toolbar">
<div class="toolbar-left">主操作、批量操作</div>
<div class="toolbar-right">分页控制等</div>
</div>
<!-- 3. 表格/表单内容 -->
...
</div>
2.3 工具栏布局
- 使用
table-toolbar作为表格上方工具栏 - 左侧
toolbar-left:新增、删除、导出等主操作 - 右侧
toolbar-right:分页、筛选等 - 使用
a-space :size="8"或display: flex; gap: 8px控制按钮间距
2.4 响应式断点(Less)
@screen-xs: 480px; // 手机
@screen-sm: 576px; // 平板
@screen-md: 768px; // 小屏
@screen-lg: 992px; // 桌面
@screen-xl: 1200px; // 大屏
@screen-xxl: 1600px; // 超大屏
三、色彩规范
3.1 主题色(CSS 变量)
通过 :root 统一管理,运行时由 themeColor 工具更新:
:root {
--app-primary-color: #2D8C8C;
--app-primary-color-hover: #2A7F7F;
--app-primary-color-light: #e6f7f7;
--app-navbar-bg: #2D8C8C;
--app-sidebar-bg: #2D8C8C;
--app-button-gap: 8px; /* 相邻按钮间距 */
}
约定:
- 主色:
var(--app-primary-color)或#2D8C8C - Hover 色:
var(--app-primary-color-hover) - 浅底(选中背景):
var(--app-primary-color-light) - 页面背景:
var(--color-bg-1)(Arco) - 内容区背景:
#fff或#f0f3f4
3.2 组件配色
- 主按钮、Switch、Tabs 指示线、菜单选中:使用主题色
- 日期选择器、Input focus:
border-color: var(--app-primary-color) - 链接激活态:
color: var(--app-primary-color)
四、字体规范
4.1 字体栈
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
"Microsoft YaHei", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
代码字体:
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
4.2 字号与行高
- 全局基准字号:
14px - 表单、按钮、输入框:
14px - 日期选择器、部分紧凑区域:
12px(如.notice内) - 菜单文字:
12px,font-weight: bold
五、组件规范
5.1 按钮
- 高度:
32px,border-radius: 4px - 图标按钮:
32px × 32px正方形 - 相邻按钮间距:统一
8px- 使用
a-space :size="8"或gap: 8px/gap: var(--app-button-gap) - 适用于工具栏、表格操作列、弹窗底部按钮组
- 使用
- 主操作使用
type="primary"
5.2 输入类(Input / Select / Picker)
- 统一高度:
32px(Input)、28px(Picker) border-radius: 4px- Focus / Hover 使用主题色 border 与 shadow
5.3 卡片 / 弹窗 / 下拉
border-radius: 8px(Card、Modal、Popover、Dropdown、Drawer、Table、Tag、Alert、Message、Notification)
5.4 Pro 系列组件
| 组件 | 用途 |
|---|---|
| FormPro | 配置驱动表单,itemList + comp + compProps |
| TablePro | VxeGrid 封装,tableConfig + api + formConfig |
| CustomList | 自定义列 + TablePro,支持列管理 |
| HandsontablePro | 类 Excel 表格 |
| ModalPro | 弹窗,配合 useModal |
| DrawerPro | 抽屉 |
| SelectPro | 增强选择器 |
| JsonEditorPro / JsonDiffPro | JSON 编辑与对比 |
| CodeMirror | 代码编辑 |
约定:
- 增强型封装统一使用
Pro后缀 - 优先使用 Pro 组件,减少重复造轮子
5.5 消息与确认
- 使用
$baseMessage、$baseConfirm(如有) - 或 Arco 的
Message、Modal.confirm、a-popconfirm
六、表单规范
6.1 布局
- 表单类型:
horizontal、vertical、inline - 标签列:
label-col-props="{ span: 6 }"(或 5) - 内容列:
wrapper-col-props="{ span: 16 }"(或 19) - FormPro:
labelColProps: { span: 5 }、wrapperColProps: { span: 19 }、rowGutter: 20、defaultSpan: 6
6.2 FormPro 配置示例
itemList: [
{
comp: 'AInput',
field: 'name',
label: '名称',
required: true,
span: 6,
rules: [{ required: true, message: '请输入名称' }],
compProps: { placeholder: '请输入' },
},
{
comp: 'ASelect',
field: 'status',
label: '状态',
compProps: { options: [...], placeholder: '请选择' },
},
]
6.3 校验
- 使用 Arco Form 的
rules - 提交前调用
formRef.validate()统一校验 - 必填项使用
required: true并配置message
七、表格规范
7.1 组件选择
| 场景 | 组件 | 说明 |
|---|---|---|
| 常规 CRUD 列表 | TablePro | 带搜索表单、分页、API 集成 |
| 自定义列 + 列管理 | CustomList | 包裹 TablePro |
| 类 Excel 编辑 | HandsontablePro | 单元格编辑、复制粘贴 |
| 简单列表(角色、菜单等) | a-table | Arco 原生 |
7.2 TablePro 配置
tableConfig:columns、toolbarConfig 等api:分页接口,参数含pageIndex、pageSize、表单值formConfig:搜索区域columnConfig.useKey: true、resizable: trueshowOverflow: 'tooltip'
7.3 分页
- 可选 pageSize:
10 / 30 / 50 / 100(按需裁剪) - 默认 pageSize:
30 - 接口参数:
pageIndex、pageSize;返回:totalCount、items或data.list
7.4 操作列
- 编辑、删除、分配等使用
a-button type="text" size="small" - 删除使用
a-popconfirm - 操作按钮需权限控制(见「权限」)
八、交互规范
8.1 弹窗 / 抽屉
- 使用
ModalPro+useModal()管理显隐与数据 - 标准流程:
openModal(true, data)→ 编辑 →setLoading(true)→ 提交 → 成功 →closeModal()、刷新列表 - 弹窗宽度:常规
600px,复杂表单800px或更高
8.2 加载与空态
- 表格:
loading状态 - 弹窗提交:
confirm-loading - 空数据:使用 Arco
Empty或统一空态组件
8.3 按钮顺序
- 主操作(确定、保存)在右侧
- 取消 / 重置在左侧
- destructive 操作(删除)单独放置,并加确认
九、权限规范
9.1 权限格式
Module.Resource.Action,如:
Rbac.Roles.CreateRbac.Users.UpdateApi.Interfaces.QueryTrack.Orders.Query
9.2 使用方式
模板:
<a-button
v-if="hasPermission('Rbac.Roles.Create')"
type="primary"
@click="handleAdd"
>
新增
</a-button>
路由:
{
path: '/system/roles',
meta: { permission: 'Rbac.Roles.Query' },
}
工具函数:
import { hasPermission, hasAnyPermission, hasAllPermissions, hasRole } from '@/utils/rbac-permission';
9.3 菜单
- 菜单基于 RBAC
menus与userMenuIdSet过滤 - 无权限的菜单项不展示
十、命名规范
10.1 文件与目录
| 类型 | 规范 | 示例 |
|---|---|---|
| 页面组件 | index.vue 置于功能目录下 |
views/api/upstreamInterface/index.vue |
| 子组件 | PascalCase 或 kebab-case | ServiceProviderInterfaceModal.vue、AccountList.vue |
| 布局组件 | kebab-case | top-nav、tab-bar、page-layout |
| 共享组件 | PascalCase | FormPro、TablePro、CustomList |
| API 模块 | camelCase 或 PascalCase | interface-serviceProvider、TrackOrder |
| Store 模块 | kebab-case | rbac-user、tab-bar、app |
| 国际化 | zh-CN.ts、en-US.ts |
locale/zh-CN.ts |
10.2 代码命名
| 类型 | 规范 |
|---|---|
| 变量 / 方法 | camelCase |
| 常量 | UPPER_SNAKE_CASE 或 camelCase |
| 类型 / 接口 | PascalCase |
| 组件名 | PascalCase |
10.3 路由
- path:camelCase,如
/api/upstreamInterface、/track/kpiEarlyWarningConfig - name:PascalCase,如
InterfaceDetailTest
10.4 国际化 Key
- 格式:
模块.资源.键或common.xxx - 示例:
system.role.actions.add、common.search、common.reset
十一、国际化规范
11.1 结构
- 根:
src/locale/zh-CN.ts、en-US.ts - 按页面拆分:
views/xxx/locale/zh-CN.ts,在根 locale 中合并
11.2 使用
<template>{{ t('common.search') }}</template>
<script setup>
const { t } = useI18n();
</script>
11.3 必备 Key
common.search、common.reset、common.add、common.delete、common.editSuccess、common.addSuccess、common.saveSuccesscommon.selectPlaceholder、common.actions、common.viewDetail
十二、API 与请求规范
12.1 分页接口
请求:
{
pageIndex: number;
pageSize: number;
// 其它搜索参数
}
响应:
{
totalCount: number;
items: T[]; // 或 data.list
}
12.2 错误处理
- 使用统一的 axios 拦截器(如
rbac-error-handler) - 401 自动跳转登录;其它错误统一提示
十三、样式约定
13.1 作用域
- 组件内使用
scoped - 覆盖第三方样式时使用
:deep()或全局类
13.2 容器类
- 页面根容器:
xxx-container(如role-page、业务相关命名),保证padding: 16px - 表格工具栏:
table-toolbar、toolbar-left、toolbar-right
13.3 按钮间距
- 相邻
arco-btn之间:margin-left: 8px(全局已统一) - 使用
a-space :size="8"包裹一组按钮
十四、检查清单(新页面开发)
- 使用
xxx-container或等效布局结构 - 工具栏使用
table-toolbar、toolbar-left、toolbar-right - 按钮、输入框符合全局样式(高度、圆角)
- 使用主题色变量,不硬编码
#2D8C8C - 弹窗 / 抽屉使用 ModalPro / DrawerPro + useModal
- 表单使用 FormPro 或统一 label/span
- 表格优先 TablePro / CustomList / HandsontablePro
- 分页 10/30/50/100,默认 30
- 操作按钮按权限使用
hasPermission - 路由 meta 配置
permission - 文案通过 i18n,不写死中文
- 命名符合本规范(文件、路由、变量、i18n key)
附录:常用代码片段
页面头部 + 权限按钮
<div class="page-header">
<a-space>
<a-button
v-if="hasPermission('Module.Resource.Create')"
type="primary"
@click="handleAdd"
>
<template #icon><icon-plus /></template>
{{ t('common.add') }}
</a-button>
</a-space>
<a-space>
<a-button @click="loadData">
<template #icon><icon-refresh /></template>
</a-button>
</a-space>
</div>
表格操作列(编辑 / 删除)
<template #action="{ record }">
<div class="action-buttons">
<a-button
v-if="hasPermission('Module.Resource.Update')"
type="text"
size="small"
@click="handleEdit(record)"
>
<IconEdit />
</a-button>
<a-popconfirm
v-if="hasPermission('Module.Resource.Delete')"
:content="t('common.deleteConfirm')"
@ok="handleDelete(record.id)"
>
<a-button type="text" size="small">
<IconDelete />
</a-button>
</a-popconfirm>
</div>
</template>
FormPro 查询表单
<FormPro
ref="formProRef"
:item-list="formItemList"
:button-config="{ showBtn: true }"
@submit="handleSearch"
@reset="handleReset"
/>
文档版本:1.0 | 更新日期:2025-03-21