# 前端布局样式系统设计
**创建日期**: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 样式:`