12 KiB
前端视觉与样式系统重构设计
日期: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动画、过度渐变)增加视觉噪音
本次重构目标是收口样式系统,让"主题改一处,全站生效",并消除明显观感问题。
范围与非范围
范围内
- 统一颜色变量系统(消除硬编码、补齐缺失变量)
- 图标库迁移:FA4 → Element Plus Icons(
@element-plus/icons-vue,已与 Element Plus 同步) - 重新设计登录页,与主应用视觉一致
- 修复
AppHeader.vue的--warning-color缺失问题 - 整理
index.scss的!important覆盖,改用更高特异性选择器 - 适度降低装饰性效果:移除按钮悬停位移、统一卡片阴影阶梯
非范围(本次不做)
- 布局结构改动(保留 260px 侧边栏 + 60px 顶栏)
- 深色模式切换
- 任何业务逻辑修改
- 移动端适配(当前项目无移动端需求)
web/静态版不动
方案选型
选定方案:方案 A — 克制重塑
保留现有"深色侧边栏 + 浅色内容区"骨架,做样式系统收口。
未选 方案 B(极简重做):改动面太广,10+ 视图都要适配,回报/风险比差。 未选 方案 C(全深色科技感):Element Plus 暗色需要大量单独调校,工作量与当前诉求不匹配。
设计
1. 颜色变量系统(src/styles/index.scss 重构)
目标:所有颜色、阴影、圆角都走 CSS 变量;后续改主题只改 :root 即可。
新增/补齐变量(src/styles/index.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 字体图标更现代
实施:
npm i @element-plus/icons-vuemain.ts全局注册常用图标(按需在组件内 import 也可)- 替换规则(在每个 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 用
sizeprop 或 CSSfont-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:扩展
src/styles/index.scss变量(新增,不删除旧的) - 步骤 2:安装
@element-plus/icons-vue,在main.ts注册 - 步骤 3:逐文件替换图标(按表格顺序)
- 步骤 4:逐文件替换硬编码颜色为变量
- 步骤 5:重新设计
LoginView.vue - 步骤 6:删除
src/assets/font-awesome/目录和main.ts的 import - 步骤 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 主题层注册暗色)