# 前端布局样式系统设计 **创建日期**:2026-01-01 **最后更新**:2026-01-09 **目标**:建立系统化的前端布局和样式规范,确保一致性和可维护性 **原则**:统一规范、可扩展、易维护、主题兼容 **状态**:✅ 已完成 Arco Design 规范优化 --- ## 📋 快速导航 - [一、设计目标](#一设计目标) - [二、布局系统](#二布局系统) - [2.1 Arco Design Layout 组件使用规范](#21-arco-design-layout-组件使用规范) - [2.2 整体布局结构](#22-整体布局结构) - [2.3 布局层次](#23-布局层次) - [三、样式系统](#三样式系统) - [十二、Arco Design 规范对照总结](#十二arco-design-规范对照总结) - [优化总结](#优化总结) --- --- ## 一、设计目标 ### 核心目标 - **一致性**:统一的布局和样式规范 - **可维护性**:清晰的样式组织结构 - **可扩展性**:支持主题切换、响应式布局、功能扩展 - **性能**:优化样式性能,减少重复代码 ### 设计原则 - 使用 Arco Design 基础样式(优先使用样式变量) - 避免硬编码样式(使用 CSS 变量和设计令牌) - 组件化样式(每个组件管理自己的样式) - 响应式优先(支持不同屏幕尺寸) --- ## 二、布局系统 ### 2.1 Arco Design Layout 组件使用规范 #### 2.1.1 Arco Layout 组件结构 Arco Design 提供了以下 Layout 组件: - `a-layout`: 布局容器 - `a-layout-header`: 顶部导航栏 - `a-layout-sider`: 侧边栏 - `a-layout-content`: 内容区域 - `a-layout-footer`: 底部栏 #### 2.1.2 我们的实现方式 **顶层布局(App.vue)** - ✅ 符合 Arco 规范 ```vue 顶部导航 内容区域 ``` **数据库客户端布局(db-cli/index.vue)** - ✅ 已优化为使用 Arco Layout 组件 ```vue 侧边栏 编辑器 结果 ``` **优化说明**: - ✅ 使用嵌套的 `a-layout` 替代自定义 `div.main-content` - ✅ 使用 `a-layout-content` 作为编辑器和结果区域 - ✅ 完全符合 Arco Design 规范 - ✅ 保持了原有的灵活性和功能(拖拽调整、百分比高度等) ### 2.2 整体布局结构 ``` ┌─────────────────────────────────────────────────────────┐ │ db-cli-layout (Arco Layout, 100vh) │ │ ┌──────────────┐ ┌─────────────────────────────────┐ │ │ │ sidebar │ │ main-content (flex:1) │ │ │ │ (280px) │ │ ┌───────────────────────────┐ │ │ │ │ │ │ │ editor-area │ │ │ │ │ sidebar- │ │ │ (height: %, 可隐藏) │ │ │ │ │ container │ │ │ └─ SqlEditor │ │ │ │ │ │ │ └───────────────────────────┘ │ │ │ │ Connection- │ │ ┌───────────────────────────┐ │ │ │ │ Tree │ │ │ editor-result-divider (4px)│ │ │ │ └──────────────┘ │ └───────────────────────────┘ │ │ │ │ ┌───────────────────────────┐ │ │ │ │ │ result-area (flex:1) │ │ │ │ │ │ └─ ResultPanel │ │ │ │ │ │ └─ Tabs │ │ │ │ │ │ ├─ result │ │ │ │ │ │ ├─ messages │ │ │ │ │ │ ├─ structure │ │ │ │ │ │ ├─ history │ │ │ │ │ │ └─ create │ │ │ │ │ └───────────────────────────┘ │ │ │ └─────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ### 2.3 布局层次 | 层级 | 元素 | Arco 组件 | 类型 | 说明 | |------|------|-----------|------|------| | **顶层(App.vue)** ||||| | 0 | layout | `a-layout` | Arco Layout | 应用主容器(100vh,垂直 Flex) | | 0.1 | header | `a-layout-header` | Arco Header | 顶部导航栏(固定高度) | | 0.2 | content | `a-layout-content` | Arco Content | 主内容区域(flex:1,可滚动) | | **数据库客户端(db-cli/index.vue)** ||||| | 1 | db-cli-layout | `a-layout` | Arco Layout | 数据库客户端容器(100%,水平 Flex) | | 2 | sidebar | `a-layout-sider` | Arco Sider | 侧边栏(280px,flex-shrink: 0) | | 2.1 | sidebar-container | - | 自定义 div | 侧边栏容器(100%高度,Flex 列) | | 3 | main-layout | `a-layout` | Arco Layout | 主布局容器(flex:1,垂直 Flex)✅ 已优化 | | 4 | editor-area | `a-layout-content` | Arco Content | 编辑器区域(百分比高度,可隐藏)✅ 已优化 | | 4.1 | editor-result-divider | - | 自定义 div | 分隔条(4px,可调整大小) | | 5 | result-area | `a-layout-content` | Arco Content | 结果区域(flex:1,min-height: 150px)✅ 已优化 | | 5.1 | result-panel-wrapper | - | 自定义 div | 结果面板容器(Flex 列) | | 5.2 | result-tabs | `a-tabs` | Arco Tabs | Tabs 容器(flex:1) | | 5.3 | tab-content | - | 自定义 div | 各 Tab 内容区域(height:100%) | **Arco 组件使用情况**(已优化): - ✅ 使用了 `a-layout` 作为容器 - ✅ 使用了 `a-layout-sider` 作为侧边栏 - ✅ 使用嵌套 `a-layout` 作为主内容区容器 ✅ **已优化** - ✅ 使用 `a-layout-content` 作为编辑器和结果区域 ✅ **已优化** - ✅ 使用了 `a-tabs` 作为结果面板的标签页 ### 2.4 Arco Layout 组件的样式特性 #### 2.4.1 Arco Layout 默认样式 Arco Design 的 Layout 组件具有以下默认样式特性: ```css /* a-layout */ .arco-layout { display: flex; flex: auto; flex-direction: column; box-sizing: border-box; } /* a-layout-header / a-layout-footer */ .arco-layout-header, .arco-layout-footer { flex: 0 0 auto; } /* a-layout-sider */ .arco-layout-sider { position: relative; min-width: 0; transition: all 0.2s; } /* a-layout-content */ .arco-layout-content { flex: auto; } ``` #### 2.4.2 我们的样式覆盖 我们为 `db-cli-layout` 覆盖了部分样式,使其适配水平布局: ```css .db-cli-layout { width: 100%; height: 100%; display: flex; flex-direction: row; /* 覆盖默认的 column,改为水平布局 */ overflow: hidden; } .sidebar { flex-shrink: 0; width: 280px; /* Arco 的 a-layout-sider 会应用默认样式,我们通过 class 覆盖特定样式 */ } ``` **注意事项**: - `a-layout` 默认是垂直 Flex(`flex-direction: column`),我们在 `.db-cli-layout` 中覆盖为水平(`row`) - `a-layout-sider` 的宽度通过 `:width="280"` prop 设置,符合 Arco 规范 ✅ - ✅ **已优化**:使用嵌套 `a-layout` 和 `a-layout-content` 替代自定义 `div.main-content` - ✅ **已优化**:所有样式使用 Arco 设计令牌,简化写法 ### 2.5 布局样式规范 #### 主布局容器 ```css .db-cli-layout { width: 100%; height: 100%; display: flex; overflow: hidden; } .sidebar { flex-shrink: 0; width: 280px; border-right: 1px solid var(--color-border-2); /* ✅ 已优化:简化边框写法 */ overflow: hidden; } .sidebar-container { height: 100%; display: flex; flex-direction: column; overflow: hidden; } /* 主布局容器 - 使用 Arco Layout */ .main-layout { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; } ``` #### 编辑器区域 - 使用 Arco Layout Content ```css .editor-area { flex-shrink: 0; min-height: 150px; display: flex; flex-direction: column; overflow: hidden; position: relative; padding: 0; /* 移除 Arco Layout Content 的默认 padding */ /* 高度通过 :style="{ height: editorAreaHeight + '%' }" 动态设置 */ } .editor-result-divider { flex-shrink: 0; height: 4px; background: var(--color-border-2); cursor: row-resize; position: relative; transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1); /* 使用 Arco 过渡函数 */ display: flex; align-items: center; justify-content: center; } .editor-result-divider:hover { background: var(--color-border-3); } .editor-result-divider.collapsed { cursor: pointer; height: 6px; } ``` #### 分隔条按钮 - 使用 Arco 设计令牌 ```css .divider-toggle-btn { position: absolute; z-index: 10; background: var(--color-bg-1); border: 1px solid var(--color-border-2); border-radius: var(--border-radius-small, 2px); /* 使用 Arco 圆角变量 */ box-shadow: var(--shadow-1-down, 0 2px 4px rgba(0, 0, 0, 0.06)); /* 使用 Arco 阴影变量 */ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); padding: 0; min-width: 30px; height: 15px; } .divider-toggle-btn:hover { background: var(--color-bg-2); border-color: var(--color-primary-light-2); box-shadow: var(--shadow-2-down, 0 4px 8px rgba(0, 0, 0, 0.1)); transform: translateY(-1px); } ``` #### 结果区域 - 使用 Arco Layout Content ```css .result-area { flex: 1; min-height: 150px; display: flex; flex-direction: column; border-top: 1px solid var(--color-border-2); /* 简化边框样式 */ overflow: hidden; position: relative; height: 100%; padding: 0; /* 移除 Arco Layout Content 的默认 padding */ } .result-panel-wrapper { height: 100%; width: 100%; display: flex; flex-direction: column; overflow: hidden; min-height: 0; } ``` ### 2.6 Arco Tabs 组件使用规范 #### 2.6.1 Arco Tabs 组件结构 Arco Design 的 Tabs 组件结构: ``` arco-tabs ├── arco-tabs-header (标签头部,flex-shrink: 0) │ └── arco-tabs-nav │ └── arco-tabs-tab (各个标签页) └── arco-tabs-content (标签内容区域,flex: 1) └── arco-tabs-content-list └── arco-tabs-content-item (各个内容项) ``` #### 2.6.2 我们的实现方式 ```vue ... ... ``` **使用规范核对**: - ✅ 使用 `v-model:active-key` 控制激活标签 - 符合 Arco 规范 - ✅ 使用 `type="line"` 设置标签样式 - 符合 Arco 规范 - ✅ 使用 `a-tab-pane` 定义各个标签页 - 符合 Arco 规范 - ✅ 使用 `key` 和 `title` 属性 - 符合 Arco 规范 #### 2.6.3 Tabs 内容区域布局 #### Arco Tabs 深度样式设置 **Arco Tabs 默认样式特性**: - `arco-tabs`: 默认 `display: flex; flex-direction: column` - `arco-tabs-header`: 默认 `flex-shrink: 0`(固定高度) - `arco-tabs-content`: 默认 `flex: 1`(占据剩余空间) **我们的样式覆盖**(确保高度计算正确): ```css .result-tabs { flex: 1; min-height: 0; height: 100%; display: flex; flex-direction: column; overflow: hidden; } /* 确保 arco-tabs 容器高度正确 */ .result-tabs :deep(.arco-tabs) { height: 100%; /* ✅ 关键:设置高度为 100% */ display: flex; flex-direction: column; overflow: hidden; } /* 内容区域占据剩余空间 */ .result-tabs :deep(.arco-tabs-content) { flex: 1; /* ✅ 符合 Arco 默认样式 */ min-height: 0; /* ✅ 关键:允许收缩 */ overflow: hidden; } /* 内容列表高度设置 */ .result-tabs :deep(.arco-tabs-content-list) { height: 100%; /* ✅ 关键:确保列表高度正确 */ } /* 各个内容项高度设置 */ .result-tabs :deep(.arco-tabs-content-item) { height: 100%; /* ✅ 关键:每个内容项高度 100% */ display: flex; /* ✅ 添加 Flex 布局支持 */ flex-direction: column; overflow: hidden; } ``` **关键点**: 1. ✅ `arco-tabs-content` 使用 `flex: 1` - 符合 Arco 默认样式 2. ✅ `arco-tabs-content-item` 使用 `height: 100%` - 确保内容项高度正确 3. ✅ 添加 `min-height: 0` - 允许 Flex 子元素正确收缩 4. ✅ 使用 `:deep()` 深度选择器覆盖 Arco 内部样式 - Vue 3 标准做法 #### Tab Content 通用样式 所有 Tab 内容都遵循相同的布局模式: ```css .tab-content { height: 100%; /* 使用 height: 100% 而非 flex: 1 */ display: flex; flex-direction: column; padding: var(--spacing-md, 12px); overflow: hidden; min-height: 0; } ``` #### 具体 Tab 内容结构 **结果 Tab (result-content)** ``` result-content (height: 100%) ├── result-loading / result-empty (flex: 1, 居中) └── result-data-wrapper (flex: 1, overflow: hidden) ├── result-stats (flex-shrink: 0) └── result-table-container / result-json-container (flex: 1) ``` **消息 Tab (messages-content)** ``` messages-content (height: 100%) └── messages-list (flex: 1, overflow-y: auto) ├── message-item (列表项) └── messages-empty (flex: 1, 居中) ``` **结构 Tab (structure-content)** ``` structure-content (height: 100%) └── structure-data (flex: 1, overflow-y: auto) └── structure-section ├── structure-section-header (flex-shrink: 0) └── structure-table-container (flex: 1) ``` **历史 Tab (history-content)** ``` history-content (height: 100%) ├── history-toolbar (flex-shrink: 0) ├── history-loading / history-empty (flex: 1, 居中) └── history-timeline-wrapper (flex: 1, overflow: hidden) ├── history-timeline (flex: 1, overflow-y: auto) └── history-pagination-wrapper (flex-shrink: 0) ``` **创建 Tab (create-content)** ``` create-content (height: 100%) └── create-content > div (flex: 1) ├── MySQLCreate / 其他组件 └── create-actions (flex-shrink: 0) ``` --- ## 三、样式系统 ### 3.1 设计令牌(Design Tokens)- Arco Design 标准 #### 间距系统 ✅ 已统一使用 ```css /* Arco Design 间距变量(优先使用) */ --spacing-xs: 4px; --spacing-sm: 8px; --spacing-md: 12px; --spacing-lg: 16px; --spacing-xl: 20px; --spacing-xxl: 24px; ``` **使用规范**: - ✅ 所有 padding 和 margin 都应使用这些变量 - ✅ 避免硬编码数值(如 `padding: 8px` → `padding: var(--spacing-sm, 8px)`) #### 颜色系统 ✅ 已统一使用 ```css /* 边框颜色 */ --color-border-1, --color-border-2, --color-border-3, --color-border-4 /* 背景颜色 */ --color-bg-1, --color-bg-2, --color-bg-3, --color-bg-4 /* 文本颜色 */ --color-text-1, --color-text-2, --color-text-3, --color-text-4 /* 主题色 */ --color-primary, --color-primary-light-1 到 light-5 ``` **使用规范**: - ✅ 简化边框写法:`1px solid var(--color-border-2)`(已优化) - ✅ 避免使用 `var(--color-border-2, var(--color-border))` 这种多层 fallback - ✅ 主题色使用 `--color-primary-light-*` 系列 #### 字体系统 ✅ 已统一使用 ```css /* Arco Design 字体大小变量 */ --font-size-xs: 12px; --font-size-sm: 13px; /* 注意:不是 14px */ --font-size-md: 14px; --font-size-lg: 16px; /* 字体族 */ --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, ...; --font-family-mono: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace; ``` **使用规范**: - ✅ 所有文本大小使用这些变量 - ✅ 代码/等宽字体使用 `--font-family-mono` #### 边框系统 ✅ 已统一使用 ```css /* 圆角 */ --border-radius-small: 2px; --border-radius-medium: 4px; --border-radius-large: 6px; /* 边框 */ border: 1px solid var(--color-border-2); /* ✅ 简化写法 */ ``` **使用规范**: - ✅ 使用 `--border-radius-small`, `--border-radius-medium`, `--border-radius-large` - ✅ 边框统一使用 `1px solid var(--color-border-2)` 简化写法 #### 阴影系统 ✅ 已统一使用 ```css /* Arco Design 阴影变量 */ --shadow-1-down: 0 2px 4px rgba(0, 0, 0, 0.06); --shadow-2-down: 0 4px 8px rgba(0, 0, 0, 0.1); --shadow-3-down: 0 8px 16px rgba(0, 0, 0, 0.12); ``` **使用规范**: - ✅ 使用 Arco 阴影变量替代硬编码 `rgba()` - ✅ hover 状态使用 `--shadow-2-down`,默认使用 `--shadow-1-down` #### 过渡函数 ✅ 已统一使用 ```css /* Arco Design 标准过渡函数 */ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); /* 或者更精确地指定属性 */ transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1); ``` **使用规范**: - ✅ 所有过渡动画使用 `cubic-bezier(0.4, 0, 0.2, 1)` - ✅ 过渡时间统一使用 `0.2s` ### 3.2 Flex 布局规范 #### Flex 容器基础规范 ```css .flex-container { display: flex; overflow: hidden; min-width: 0; /* 关键:允许 flex 子元素收缩 */ min-height: 0; /* 关键:允许 flex 子元素收缩 */ } ``` #### 高度计算关键点 **1. Flex 容器中的高度计算** - 使用 `height: 100%` 而非 `flex: 1` 作为子元素高度设置 - 必须设置 `min-height: 0` 允许 flex 子元素正确收缩 - 滚动容器应该使用 `overflow-y: auto` 而非 `overflow: hidden` **2. Arco Tabs 内容区域高度设置** ```css /* Arco Tabs 内容项必须使用 height: 100% */ .arco-tabs-content-item { height: 100%; display: flex; flex-direction: column; overflow: hidden; } /* Tab Content 使用 height: 100% 而非 flex: 1 */ .tab-content { height: 100%; /* ✅ 正确 */ /* flex: 1; ❌ 错误,会导致高度计算不准确 */ } ``` **3. 滚动容器的正确设置** ```css /* 滚动容器应该设置在内容区域,而非外层容器 */ .scroll-container { flex: 1; overflow-y: auto; /* 滚动设置在内容层 */ overflow-x: hidden; min-height: 0; /* 必须设置 */ } /* 外层容器隐藏溢出 */ .outer-container { overflow: hidden; /* 外层隐藏溢出 */ min-height: 0; } ``` ### 3.3 组件样式规范(BEM 命名) ```css .component-wrapper { } .component-header { } .component-content { } .component-item--active { } .component-item--disabled { } ``` **样式组织顺序**:容器样式 → 布局样式 → 功能样式 → 状态样式 → 深度选择器 --- ## 四、响应式设计 ### 4.1 断点定义 ```css --breakpoint-xs: 480px; --breakpoint-sm: 768px; --breakpoint-md: 992px; --breakpoint-lg: 1200px; --breakpoint-xl: 1600px; ``` ### 4.2 响应式策略 | 屏幕尺寸 | 策略 | |---------|------| | < 768px | 侧边栏折叠/隐藏,编辑器/结果区域垂直堆叠 | | 768px - 1200px | 保持当前布局,适当调整比例 | | > 1200px | 保持当前布局,可增加侧边栏宽度 | --- ## 五、主题支持 - **优先使用 Arco Design 主题变量**:`var(--color-*)`、`var(--spacing-*)` - **避免硬编码颜色**:确保主题切换时样式正确 - **测试主题兼容性**:在明暗主题下测试样式 --- ## 六、样式最佳实践 ### 推荐做法 ✅ 1. 使用 Arco Design 变量:`padding: var(--spacing-md); color: var(--color-text-1);` 2. 使用 Flex 布局:`display: flex; flex-direction: column; overflow: hidden; min-height: 0;` 3. 使用 scoped 样式:`