# 前端视觉与样式系统重构设计 **日期**:2026-07-09 **范围**:`frontend/` (Vue 3 + Element Plus + Pinia) **目标用户**:内部数据/算法工程师,桌面端浏览器使用 ## 背景与动机 当前前端已用 Element Plus + 自定义 SCSS 变量搭起一套"深色侧边栏 + 浅色内容区"的现代 B 端布局,但实际页面观感"乱"且有功能性瑕疵,根因不是设计语言本身有问题,而是**设计系统没有真正落地**: - 颜色散落硬编码(`#1e293b`、`#475569`、`#909399`、`#1890ff`、`#67c23a`…) - Element Plus 旧默认色与新主题色(`#4f46e5`)并存 - 用了 FontAwesome **4.7.0**(2017 年停止维护),大量 `fa-cogs`/`fa-hdd-o` 这种短横线后缀命名 - 登录页(`LoginView.vue`)背景是纯色 `#dbe0f9`,与主应用玻璃拟态风格割裂 - `AppHeader.vue:189` 引用了主题里**不存在**的 `--warning-color` 变量,导致回退到默认值 - `index.scss` 内有 5+ 处 `!important`,说明覆盖策略不对 - 装饰性动画(按钮悬停 `translateY(-1px)`、`pulse` 动画、过度渐变)增加视觉噪音 本次重构目标是**收口样式系统**,让"主题改一处,全站生效",并消除明显观感问题。 ## 范围与非范围 ### 范围内 1. 统一颜色变量系统(消除硬编码、补齐缺失变量) 2. 图标库迁移:FA4 → **Element Plus Icons**(`@element-plus/icons-vue`,已与 Element Plus 同步) 3. 重新设计登录页,与主应用视觉一致 4. 修复 `AppHeader.vue` 的 `--warning-color` 缺失问题 5. 整理 `index.scss` 的 `!important` 覆盖,改用更高特异性选择器 6. 适度降低装饰性效果:移除按钮悬停位移、统一卡片阴影阶梯 ### 非范围(本次不做) - 布局结构改动(保留 260px 侧边栏 + 60px 顶栏) - 深色模式切换 - 任何业务逻辑修改 - 移动端适配(当前项目无移动端需求) - `web/` 静态版不动 ## 方案选型 ### 选定方案:方案 A — 克制重塑 保留现有"深色侧边栏 + 浅色内容区"骨架,做样式系统收口。 **未选 方案 B(极简重做)**:改动面太广,10+ 视图都要适配,回报/风险比差。 **未选 方案 C(全深色科技感)**:Element Plus 暗色需要大量单独调校,工作量与当前诉求不匹配。 ## 设计 ### 1. 颜色变量系统(`src/styles/index.scss` 重构) **目标**:所有颜色、阴影、圆角都走 CSS 变量;后续改主题只改 `:root` 即可。 **新增/补齐变量**(`src/styles/index.scss` 顶部): ```scss :root { /* Element Plus 主色(已有) */ --el-color-primary: #4f46e5; --el-color-primary-light-3: #818cf8; --el-color-primary-light-5: #a5b4fc; --el-color-primary-light-7: #c7d2fe; --el-color-primary-light-8: #e0e7ff; --el-color-primary-light-9: #eef2ff; --el-color-primary-dark-2: #4338ca; /* 状态色(已有) */ --el-color-success: #10b981; --el-color-warning: #f59e0b; /* 修复:之前未显式定义 */ --el-color-danger: #ef4444; --el-color-info: #64748b; /* 项目别名(已有 + 新增) */ --primary-color: var(--el-color-primary); --primary-hover: var(--el-color-primary-light-3); --success-color: var(--el-color-success); --warning-color: var(--el-color-warning); /* 新增:修复 AppHeader 引用 */ --danger-color: var(--el-color-danger); /* 圆角(已有) */ --el-border-radius-base: 8px; --el-border-radius-small: 6px; --el-border-radius-round: 20px; /* ========== 新增:项目语义化变量 ========== */ /* 文字 */ --text-primary: #1e293b; /* 替代硬编码 #1e293b */ --text-secondary: #475569; /* 替代 #475569 */ --text-tertiary: #64748b; /* 替代 #64748b */ --text-placeholder: #94a3b8; /* 替代 #94a3b8 */ /* 背景 */ --bg-page: #f8fafc; /* 替代 --el-bg-color-page */ --bg-card: #ffffff; --bg-subtle: #f1f5f9; /* 替代硬编码 #f1f5f9 */ --bg-hover: #f8fafc; /* 替代硬编码 #f8fafc */ /* 边框 */ --border-subtle: #e2e8f0; /* 替代硬编码 #e2e8f0 */ --border-base: #f1f5f9; /* 替代硬编码 #f1f5f9 */ /* 侧边栏(已有) */ --sidebar-bg: #0f172a; --sidebar-text: #94a3b8; --sidebar-active-bg: rgba(79, 70, 229, 0.15); --sidebar-active-text: #ffffff; --sidebar-section-title: #64748b; /* 阴影(统一阶梯) */ --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04); --shadow-md: 0 2px 8px rgba(15, 23, 42, 0.06); /* 替代 --card-shadow */ --shadow-lg: 0 8px 24px rgba(15, 23, 42, 0.08); --shadow-dialog: 0 20px 40px rgba(15, 23, 42, 0.12); /* 尺寸 */ --header-height: 60px; --sidebar-width: 260px; --content-padding-x: 32px; --content-padding-y: 32px; } ``` **改动原则**: - 组件 SCSS 内的硬编码颜色全部替换为对应变量 - 任何新增颜色需求都先在 `:root` 定义,再引用 - 不再使用 `!important`;如确需覆盖,提升特异性(如 `:deep(.el-button)`) ### 2. 图标库迁移:FA4 → Element Plus Icons **为什么选 Element Plus Icons**: - 零新增依赖成本(仅在 `package.json` 增加一行) - 与 Element Plus 组件视觉风格天然一致 - 树摇友好,按需引入 - SVG 渲染,可继承 `currentColor` 与 `font-size`,比 FA 字体图标更现代 **实施**: 1. `npm i @element-plus/icons-vue` 2. `main.ts` 全局注册常用图标(按需在组件内 import 也可) 3. 替换规则(在每个 view/component 内做局部替换): | FA4 类名 | Element Plus 图标 | 用在哪 | |---------|------------------|--------| | `fa-cogs` | `Setting` | 侧边栏"模型调优" | | `fa-line-chart` | `TrendCharts` | 侧边栏"模型评测" | | `fa-server` | `Monitor` | 侧边栏"模型推理" | | `fa-cube` | `Box` | 侧边栏"模型管理"、Logo | | `fa-file-text` | `Document` | 侧边栏"数据集" | | `fa-wrench` | `Tools` | 侧边栏"其他工具" | | `fa-bar-chart` | `DataAnalysis` | 侧边栏"平台性能" | | `fa-search` | `Search` | 搜索框前缀 | | `fa-plus` | `Plus` | 新建按钮 | | `fa-trash` | `Delete` | 删除按钮 | | `fa-arrow-left` | `ArrowLeft` | 返回按钮 | | `fa-microchip` | `Cpu` | 性能监控 | | `fa-database` | `Files` | 内存监控(数据文件堆) | | `fa-hdd-o` | `Box` | 磁盘监控(存储箱) | | `fa-sign-out` | `SwitchButton` | 退出登录 | | `fa-angle-down` | `ArrowDown` | 下拉箭头 | | `fa-user-circle-o` | `User` | 个人中心 | | `fa-cog` | `Setting` | 系统设置 | | `fa-stop-circle-o` | `VideoPause` | 停止训练 | | `fa-pencil` | `Edit` | 编辑 | | `fa-times` | `Close` | 关闭 | | `fa-globe` | `Connection` | 网络流量 | | `fa-info-circle` | `InfoFilled` | 系统信息 | | `fa-user-o` | `User` | 登录页账号图标 | | `fa-lock-o` | `Lock` | 登录页密码图标 | | `fa-sign-in` | `Right` | 登录按钮 | **注意点**: - 替换后调整图标尺寸(Element Plus Icons 用 `size` prop 或 CSS `font-size`) - 部分 FA4 类名(如 `fa-file-text-o`)在 FA5/FA6 已无 `-o` 后缀 - `main.ts` 中删除 `import '@/assets/font-awesome/css/font-awesome.min.css'` - 删 `src/assets/font-awesome/` 整个目录(字体文件 100+KB) ### 3. 登录页重新设计(`LoginView.vue`) **目标**:与主应用保持一致的视觉语言,背景改用渐变 + 玻璃卡片。 **设计**: - 背景:渐变 `linear-gradient(135deg, #4f46e5 0%, #818cf8 50%, #c7d2fe 100%)` - 卡片:白色,圆角 16px,阴影 `var(--shadow-dialog)` - Logo 区域:上下结构(Logo 48px → 标题 24px → 副标题 14px 灰色) - 表单:单项之间 20px 间距,输入框 44px 高,圆角 8px - 按钮:主色实心,44px 高,全宽 - 选项行:flex 布局,记住密码左、忘记密码右 - 整体居中,最大宽 420px **关键 CSS 改动**: - 背景从 `#dbe0f9` 改为 `linear-gradient(135deg, #4f46e5 0%, #818cf8 50%, #c7d2fe 100%)` - 卡片圆角从 12px 提升到 16px - 阴影替换为 `var(--shadow-dialog)` - 所有内联颜色改用变量 ### 4. 修复 `AppHeader.vue` 的 `--warning-color` 缺失 **问题**:`AppHeader.vue:189` 使用 `var(--warning-color)`,但 `index.scss` 里只定义了 `--danger-color`、`--success-color`,没有 `--warning-color`。 **修复**:在 `:root` 中新增 `--warning-color: var(--el-color-warning);`(已在第 1 节列入)。 ### 5. 整理 `index.scss` 的 `!important` **现有 `!important` 用法**(来自 `index.scss`): | 选择器 | 用途 | 现状 | |--------|------|------| | `.el-card { border: none !important; ... }` | 去掉 EP 默认边框 | 提升为 `.app-container .el-card` 或全局加 `:where()` 重置 | | `.el-tag { border: none !important; ... }` | 去掉 EP 默认边框 | 同上 | | `.el-dialog { border-radius: 16px !important; ... }` | 圆角和阴影 | 同上 | **改写策略**: - 用更高特异性选择器(如 `body .el-card`)替代 `!important` - 或用 CSS Layer (`@layer reset, overrides, components`) 控制优先级 **本次采用**:直接提高特异性,避免引入 CSS Layer 复杂度(属于项目既定风格之外的引入,需要权衡)。 ### 6. 降低装饰性效果 **调整清单**: - `index.scss` 移除 `.el-button:hover { transform: translateY(-1px); box-shadow: ...; }` — 改为仅改变背景色 - `AppHeader.vue` 移除 `pulse` 动画,改为静态红色 - 侧边栏菜单图标的 `transform: scale(1.1)` 悬停动画保留(这是细节点缀,不算噪音) - 卡片悬停 `transform` 动效保留(仅在 DataTablePage 等列表卡片上,目前没有,不新增) - 顶栏 `backdrop-filter: blur(12px)` 保留(玻璃感是这个项目的风格语言) ## 实施步骤(落地顺序) 按风险从低到高,便于逐步验证: 1. **步骤 1**:扩展 `src/styles/index.scss` 变量(新增,不删除旧的) 2. **步骤 2**:安装 `@element-plus/icons-vue`,在 `main.ts` 注册 3. **步骤 3**:逐文件替换图标(按表格顺序) 4. **步骤 4**:逐文件替换硬编码颜色为变量 5. **步骤 5**:重新设计 `LoginView.vue` 6. **步骤 6**:删除 `src/assets/font-awesome/` 目录和 `main.ts` 的 import 7. **步骤 7**:运行 `npm run type-check` 和 `npm run build` 验证 每步完成后截图(手动)确认未引入新问题。 ## 验证标准 - [ ] `npm run type-check` 通过 - [ ] `npm run build` 通过 - [ ] 浏览器控制台无 CSS 警告(无未定义变量) - [ ] 全站不再有 `#1890ff`、`#67c23a`、`#e6a23c`、`#f56c6c` 这类 EP 旧色硬编码(grep 验证) - [ ] 全站不再有 `class="fa fa-` 的引用(grep 验证) - [ ] 全站不再有 `--warning-color` 这类指向不存在变量的引用 - [ ] `grep -c "!important" src/styles/index.scss` 数量从当前值下降 50% 以上 - [ ] 登录页与主应用风格一致 ## 风险与回退 - **风险 1**:Element Plus Icons 不覆盖某些冷门 FA 图标(如 `fa-stop-circle-o` 训练停止) - **应对**:在替换前先做一次图标对照表,确认每个 FA 类名都有 EP 对应项;没有则保留 FA4(不删除 FA 资源),但推进用 EP 主流图标 - **风险 2**:CSS 变量替换漏掉某处导致视觉回退 - **应对**:分阶段提交,每阶段都跑 build;如有遗漏,EP 会回退到自身默认色 - **风险 3**:`!important` 整理引入新覆盖问题 - **应对**:整理前先 `git diff` 对比编译产物颜色变化,保留 `git stash` 能力 ## 后续优化(不在本次范围) - 抽出 Design Token 文件(`tokens.scss`)做 Figma → Code 同步 - 引入 UnoCSS 或 Windi CSS 做原子化样式(取决于团队接受度) - 给所有列表页加 skeleton 加载态 - 暗色模式支持(需要先在 EP 主题层注册暗色)