front/docs/中后台前端页面设计规范.md
2026-03-21 15:20:52 +08:00

12 KiB
Raw Blame History

中后台前端页面设计规范

基于 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: true
  • showOverflow: '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.Create
  • Rbac.Users.Update
  • Api.Interfaces.Query
  • Track.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.saveSuccess
  • common.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