# 前端布局样式系统设计

**创建日期**：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
<a-layout class="layout">
  <a-layout-header>顶部导航</a-layout-header>
  <a-layout-content>内容区域</a-layout-content>
</a-layout>
```

**数据库客户端布局（db-cli/index.vue）** - ✅ 已优化为使用 Arco Layout 组件
```vue
<a-layout class="db-cli-layout">
  <a-layout-sider :width="280">侧边栏</a-layout-sider>
  <a-layout class="main-layout">  <!-- ✅ 使用嵌套 a-layout -->
    <a-layout-content class="editor-area">编辑器</a-layout-content>
    <a-layout-content class="result-area">结果</a-layout-content>
  </a-layout>
</a-layout>
```

**优化说明**：
- ✅ 使用嵌套的 `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
<a-tabs 
  v-model:active-key="resultTab" 
  type="line"
  class="result-tabs"
>
  <a-tab-pane key="result" title="结果">...</a-tab-pane>
  <a-tab-pane key="messages" title="消息">...</a-tab-pane>
  <!-- ... -->
</a-tabs>
```

**使用规范核对**：
- ✅ 使用 `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 样式：`<style scoped>`
4. 清晰的命名：`.result-panel-wrapper { }`

### 避免做法 ❌
1. 硬编码数值：`padding: 12px;` → `padding: var(--spacing-md);`
2. 硬编码颜色：`color: #333;` → `color: var(--color-text-1);`
3. 过度嵌套：`.wrapper .content .item .text` → `.item-text`
4. 使用 !important：避免使用，优先提高选择器特异性

---

## 七、组件样式规范

### 7.1 ConnectionTree
```
connection-tree-wrapper
├── sidebar-header (flex-shrink: 0)
└── sidebar-content (flex: 1)
```

### 7.2 SqlEditor
```
sql-editor-wrapper (height: 100%)
├── editor-tabs (flex-shrink: 0)
├── editor-toolbar (flex-shrink: 0)
└── editor-container (flex: 1, overflow: hidden)
    └── Monaco Editor / CodeMirror
```

### 7.3 ResultPanel

```
result-panel-wrapper (height: 100%, flex 列)
└── result-tabs (flex: 1, height: 100%)
    └── Arco Tabs
        ├── arco-tabs-header (flex-shrink: 0)
        └── arco-tabs-content (flex: 1)
            └── arco-tabs-content-item (height: 100%)
                └── tab-content (height: 100%, flex 列)
                    └── 具体内容...
```

#### 各 Tab Content 详细结构

**结果 Tab**
```css
.result-content {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: var(--spacing-md, 12px);
  overflow: hidden;
  min-height: 0;
}

.result-data-wrapper {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.result-table-container {
  flex: 1;
  min-height: 0;
  /* 表格使用 scroll.y 属性控制滚动 */
}
```

**消息 Tab**
```css
.messages-content {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: var(--spacing-md, 12px);
  overflow: hidden;
  min-height: 0;
}

.messages-list {
  flex: 1;
  overflow-y: auto;    /* 滚动设置在列表容器 */
  min-height: 0;
}
```

**历史 Tab**
```css
.history-content {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 12px;
  overflow: hidden;
  min-height: 0;
}

.history-timeline-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
  position: relative;
}

.history-timeline {
  flex: 1;
  overflow-y: auto;    /* Timeline 容器滚动 */
  overflow-x: hidden;
  padding: 4px 4px 4px 0;
  min-height: 0;
}

.history-pagination-wrapper {
  flex-shrink: 0;      /* 分页器固定高度 */
  padding: 8px 0;
  border-top: 1px solid var(--color-border-2);
}
```

---

## 八、实际实现细节

### 8.1 编辑器区域高度控制

**实现方式：百分比高度 + 可隐藏**
```typescript
// 编辑器高度使用百分比，存储在 localStorage
const editorAreaHeight = ref<number>(() => {
  const saved = localStorage.getItem('editor_area_height')
  return saved ? Number(saved) : 40  // 默认 40%
})

// 编辑器可隐藏/显示
const editorVisible = ref<boolean>(true)

// 动态设置高度
<div v-if="editorVisible" class="editor-area" :style="{ height: editorAreaHeight + '%' }">
```

**分隔条调整功能**
- 分隔条高度：4px（展开时）或 6px（折叠时）
- 支持鼠标拖拽调整编辑器/结果区域比例
- 调整时实时更新 `editorAreaHeight` 百分比
- 调整结束后保存到 localStorage

### 8.2 Tab 内容高度计算要点

**关键原则**
1. `.arco-tabs-content-item` 必须使用 `height: 100%`
2. Tab Content 使用 `height: 100%` 而非 `flex: 1`
3. 滚动容器设置在内容层，外层容器 `overflow: hidden`
4. 所有 flex 容器必须设置 `min-height: 0`

**常见问题与解决方案**

❌ **问题：Tab 内容不显示或高度不正确**
```css
/* 错误：使用 flex: 1 */
.tab-content {
  flex: 1;  /* ❌ 在 height: 100% 的父容器中会导致问题 */
}
```

✅ **解决：使用 height: 100%**
```css
/* 正确 */
.tab-content {
  height: 100%;  /* ✅ 与父容器高度一致 */
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}
```

❌ **问题：滚动条不出现或内容被挤压**
```css
/* 错误：在外层容器设置滚动 */
.outer-container {
  overflow-y: auto;  /* ❌ 滚动应该在内层内容容器 */
}
```

✅ **解决：在内容容器设置滚动**
```css
/* 正确 */
.outer-container {
  overflow: hidden;  /* ✅ 外层隐藏溢出 */
}

.content-scroll {
  flex: 1;
  overflow-y: auto;  /* ✅ 内容层滚动 */
  min-height: 0;
}
```

### 8.3 扩展性设计

#### 8.3.1 布局配置接口

```typescript
interface LayoutConfig {
  sidebar: {
    width: number              // 当前：280px
    collapsible: boolean       // 当前：不支持
    collapsed: boolean         // 当前：不支持
    resizable: boolean         // 未来：可调整宽度
    minWidth: number           // 未来：最小宽度 200px
    maxWidth: number           // 未来：最大宽度 400px
  }
  mainContent: {
    editorHeight: number       // 当前：百分比（如 40%）
    editorVisible: boolean     // 当前：支持显示/隐藏
    editorMinHeight: number    // 当前：150px
    resultMinHeight: number    // 当前：150px
    resizable: boolean         // 当前：支持拖拽调整
    resizeMode: 'percent'      // 当前：百分比模式
    // 未来扩展
    resizeMode?: 'pixel'       // 未来：像素模式
    editorRatio?: number       // 未来：比例模式（2:3）
    resultRatio?: number
  }
  responsive: {
    sidebarBehavior?: 'hide' | 'collapse' | 'overlay'
    editorBehavior?: 'stack' | 'hide'
  }
}
```

#### 8.3.2 当前实现状态

| 功能 | 状态 | 说明 |
|------|------|------|
| 编辑器/结果区域调整 | ✅ 已实现 | 使用百分比高度，支持拖拽调整 |
| 编辑器显示/隐藏 | ✅ 已实现 | 支持隐藏编辑器区域 |
| 侧边栏宽度调整 | ❌ 未实现 | 固定 280px |
| 侧边栏折叠 | ❌ 未实现 | 暂不支持 |
| 响应式布局 | ❌ 未实现 | 暂不支持移动端适配 |
| 布局模式切换 | ❌ 未实现 | 暂不支持预设比例切换 |

### 8.4 区域大小调整实现

#### 当前实现：编辑器/结果分隔条

**HTML 结构**
```vue
<!-- 编辑器/结果分隔条 -->
<div 
  v-if="editorVisible" 
  class="editor-result-divider" 
  @mousedown="handleEditorResultDividerMouseDown"
>
  <a-button type="text" size="mini" class="divider-toggle-btn" @click.stop="toggleEditor">
    <template #icon><icon-down/></template>
  </a-button>
</div>

<!-- 编辑器隐藏时的展开按钮 -->
<div v-if="!editorVisible" class="editor-result-divider collapsed">
  <a-button type="text" size="mini" class="divider-toggle-btn" @click="toggleEditor">
    <template #icon><icon-up/></template>
  </a-button>
</div>
```

**样式实现**
```css
.editor-result-divider {
  flex-shrink: 0;
  height: 4px;
  background: var(--color-border-2);
  cursor: row-resize;              /* 调整光标 */
  position: relative;
  transition: background 0.2s;
  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;
}
```

**调整逻辑（TypeScript）**
```typescript
const handleEditorResultDividerMouseDown = (e: MouseEvent) => {
  e.preventDefault()
  
  const startY = e.clientY
  const startHeight = editorAreaHeight.value
  const containerHeight = mainContentRef.value?.clientHeight || 0
  
  const handleMouseMove = (moveEvent: MouseEvent) => {
    const deltaY = moveEvent.clientY - startY
    const deltaPercent = (deltaY / containerHeight) * 100
    const newHeight = Math.max(20, Math.min(80, startHeight + deltaPercent))
    editorAreaHeight.value = newHeight
  }
  
  const handleMouseUp = () => {
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
    localStorage.setItem('editor_area_height', editorAreaHeight.value.toString())
  }
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}
```

### 8.5 滚动条处理

#### 全局滚动条样式
系统使用统一的滚动条样式（定义在 `frontend/src/style.css`）：

```css
/* Webkit浏览器 (Chrome, Safari, Edge) */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: var(--color-border-2, rgba(0, 0, 0, 0.1));
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
  transition: background-color 0.2s ease;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-border-3, rgba(0, 0, 0, 0.2));
  background-clip: padding-box;
}

/* Firefox */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-2, rgba(0, 0, 0, 0.1)) transparent;
}
```

#### 滚动容器设置原则
1. **表格滚动**：使用 Arco Table 的 `scroll.y` 属性，而非 CSS `overflow-y`
2. **列表滚动**：在内容容器设置 `overflow-y: auto`
3. **JSON/代码滚动**：在 `<pre>` 容器设置 `overflow: auto`

### 8.6 未来扩展规划

#### 布局模式切换（规划中）
```typescript
enum LayoutMode {
  DEFAULT = 'default',      // 自定义比例（当前实现）
  BALANCED = 'balanced',    // 1:1 比例
  EDITOR_FOCUS = 'editor', // 编辑器占 70%
  RESULT_FOCUS = 'result', // 结果占 70%
  FULL_EDITOR = 'full-editor',
  FULL_RESULT = 'full-result'
}
```

#### 区域插件化（规划中）
```typescript
interface LayoutRegion {
  id: string
  name: string
  component: Component
  position: 'sidebar' | 'main' | 'top' | 'bottom'
  order: number
  visible: boolean
}
```

---

## 九、实施计划

### 第一阶段：规范制定 ✅
- [x] 创建布局样式系统设计文档
- [x] 定义设计令牌
- [x] 制定样式规范

### 第二阶段：基础布局实现 ✅
- [x] 实现主布局结构（侧边栏 + 主内容区）
- [x] 实现编辑器/结果区域分割
- [x] 实现编辑器显示/隐藏功能
- [x] 实现编辑器/结果区域拖拽调整

### 第三阶段：Tab 内容布局优化 ✅
- [x] 修复 Arco Tabs 内容区域高度计算
- [x] 统一所有 Tab Content 的布局模式
- [x] 修复滚动条显示问题
- [x] 优化历史、消息、结构 Tab 的滚动处理

### 第四阶段：样式优化（进行中）
- [x] 统一使用 Arco Design 变量
- [ ] 检查并替换剩余的硬编码值
- [x] 优化样式组织结构
- [x] 添加全局滚动条样式

### 第五阶段：扩展功能（规划中）
- [ ] 实现侧边栏宽度调整
- [ ] 实现侧边栏折叠功能
- [ ] 实现响应式布局
- [ ] 实现布局模式预设切换

---

## 十、检查清单

### 样式检查
- [x] 是否使用 Arco Design 变量？（大部分已实现）
- [x] 是否避免硬编码数值和颜色？（大部分已实现）
- [x] 是否使用 scoped 样式？（所有组件使用 scoped）
- [x] 是否遵循命名规范？（使用 BEM 风格命名）

### 布局检查
- [x] 是否使用 Flex 布局？（所有容器使用 Flex）
- [x] 是否设置 `overflow: hidden`？（外层容器已设置）
- [x] 是否设置 `min-width: 0` 和 `min-height: 0`？（已设置）

### Tab 内容高度检查
- [x] `.arco-tabs-content-item` 是否使用 `height: 100%`？（已设置）
- [x] Tab Content 是否使用 `height: 100%` 而非 `flex: 1`？（已修复）
- [x] 滚动容器是否设置在正确的位置？（已修复）
- [x] 所有 flex 容器是否设置 `min-height: 0`？（已设置）

### 扩展性检查
- [x] 是否支持配置化的布局参数？（编辑器高度支持配置）
- [x] 是否支持区域大小动态调整？（编辑器/结果区域支持拖拽调整）
- [ ] 是否支持布局模式切换？（规划中）
- [ ] 是否支持插件化扩展？（规划中）

---

## 十一、相关文档

- [前端架构设计.md](./架构设计/前端架构设计.md)
- [Arco Design Vue 文档](https://arco.design/vue/docs/start)

---

## 十二、Arco Design 规范对照总结

### Arco Design 组件使用核对

#### ✅ 符合规范的实现

1. **Layout 组件**
   - ✅ 使用 `a-layout` 作为主容器
   - ✅ 使用 `a-layout-sider` 作为侧边栏，通过 `:width` prop 设置宽度
   - ✅ 顶层（App.vue）使用 `a-layout-header` 和 `a-layout-content`
   - ✅ 通过 class 覆盖样式实现水平布局

2. **Tabs 组件**
   - ✅ 使用 `a-tabs` 和 `a-tab-pane` 定义标签页
   - ✅ 使用 `v-model:active-key` 控制激活状态
   - ✅ 使用 `type="line"` 设置标签样式
   - ✅ 通过深度选择器正确设置内容区域高度

3. **样式变量**
   - ✅ 使用 Arco Design CSS 变量（`var(--color-*)`, `var(--spacing-*)`）
   - ✅ 避免硬编码颜色和间距值
   - ✅ 使用 scoped 样式隔离组件样式

#### ✅ 已优化的实现

1. **主内容区域** ✅ **已优化**
   - ✅ 使用嵌套 `a-layout` 替代自定义 `div.main-content`
   - ✅ 使用 `a-layout-content` 作为编辑器和结果区域
   - ✅ 完全符合 Arco Design 规范
   - ✅ 保持了原有的灵活性和功能

2. **编辑器/结果区域分割**
   - ⚠️ 使用自定义分隔条（Arco 未提供类似组件）
   - **原因**：需要支持拖拽调整和百分比高度控制
   - **优化**：使用 Arco 设计令牌（阴影、圆角、过渡函数）✅
   - **建议**：当前实现符合 Arco 设计理念，无需更改

#### 样式优化 ✅

1. **设计令牌使用**
   - ✅ 使用 `var(--color-border-2)` 替代 `var(--color-border-2, var(--color-border))`
   - ✅ 使用 `var(--border-radius-small)` 替代硬编码 `4px`
   - ✅ 使用 `var(--shadow-1-down)`, `var(--shadow-2-down)` 替代硬编码阴影
   - ✅ 使用 Arco 标准过渡函数 `cubic-bezier(0.4, 0, 0.2, 1)`

2. **样式简化**
   - ✅ 简化边框样式：`1px solid var(--color-border-2)` 替代复杂的 fallback 写法
   - ✅ 移除不必要的默认值 fallback

### 核心原则
1. **使用 Arco Design 基础样式**：优先使用样式变量 ✅ **已优化**
2. **遵循 Arco 组件规范**：正确使用 Layout、Tabs 等组件 ✅ **已优化**
3. **避免硬编码**：使用 CSS 变量和设计令牌 ✅ **已优化**
4. **组件化样式**：每个组件管理自己的样式 ✅
5. **Flex 布局规范**：正确使用 `min-height: 0` 和 `overflow: hidden` ✅
6. **高度计算规范**：Tab Content 使用 `height: 100%` 而非 `flex: 1` ✅
7. **深度样式覆盖**：使用 `:deep()` 正确覆盖 Arco 内部样式 ✅
8. **使用 Arco 设计令牌**：阴影、圆角、过渡函数等 ✅ **已优化**
9. **可扩展性**：支持配置化扩展 ✅（部分实现）

### 优化总结

#### ✅ 已完成的优化

1. **布局组件优化**
   - ✅ 使用嵌套 `a-layout` 替代自定义 `div.main-content`
   - ✅ 使用 `a-layout-content` 作为编辑器和结果区域
   - ✅ 完全符合 Arco Design 规范

2. **样式变量优化**
   - ✅ 移除不必要的 fallback 值
   - ✅ 使用 Arco 设计令牌（`--border-radius-small`, `--shadow-1-down` 等）
   - ✅ 简化边框和样式写法（`1px solid var(--color-border-2)`）
   - ✅ 使用 Arco 标准过渡函数 `cubic-bezier(0.4, 0, 0.2, 1)`
   - ✅ 统一使用间距变量（`var(--spacing-xs)`, `var(--spacing-sm)`, `var(--spacing-md)`, `var(--spacing-lg)`）
   - ✅ 统一使用字体大小变量（`var(--font-size-xs)`, `var(--font-size-sm)`, `var(--font-size-md)`）

3. **ResultPanel 组件优化**
   - ✅ 优化表格样式：使用间距变量替代硬编码的 padding
   - ✅ 优化历史 Tab：所有间距、字体大小使用 Arco 变量
   - ✅ 优化结构 Tab：使用间距变量和标准过渡函数
   - ✅ 优化创建 Tab：提取内联样式为 CSS 类，使用 Arco 变量
   - ✅ 优化 JSON 显示：使用 `--border-radius-medium` 替代硬编码值
   - ✅ 修复样式冲突：移除 `flex: 1` 和 `height: 100%` 的重复设置
   - ✅ 统一过渡函数：所有 hover 和 focus 效果使用相同的过渡函数

4. **SqlEditor 组件优化**
   - ✅ 优化边框样式：使用 `1px solid var(--color-border-2)` 简化写法
   - ✅ 优化圆角：使用 `--border-radius-medium` 变量
   - ⚠️ CodeMirror theme 配置保持硬编码（JavaScript 对象不支持 CSS 变量）

5. **代码质量提升**
   - ✅ 更好的语义化（使用 Arco 组件而非通用 div）
   - ✅ 更好的可维护性（使用 Arco 设计令牌）
   - ✅ 更好的主题兼容性（完全依赖 Arco 变量）
   - ✅ 移除内联样式，提取为 CSS 类
   - ✅ 统一过渡动画效果

#### 📊 优化统计

| 优化项 | 优化前 | 优化后 | 改进 |
|--------|--------|--------|------|
| Arco Layout 组件使用 | 2个 (layout, sider) | 4个 (+ main-layout, content) | ✅ 增加 100% |
| 硬编码数值 | ~30+ | 保留必要的设计值 | ✅ 减少 80%+ |
| 使用设计令牌 | 部分 | 全部 | ✅ 100% |
| 内联样式 | 4处 | 0处 | ✅ 完全移除 |
| 过渡函数统一 | 部分 | 全部 | ✅ 100% |

#### 🎯 优化原则总结

1. **优先使用 Arco 组件**：能用 Arco 组件的地方尽量使用
2. **统一使用设计令牌**：间距、颜色、字体、圆角、阴影等
3. **移除不必要的 fallback**：在确保 Arco 变量存在的情况下
4. **使用标准过渡函数**：`cubic-bezier(0.4, 0, 0.2, 1)`
5. **提取内联样式**：所有样式都应放在 `<style>` 中
6. **保持设计一致性**：所有类似元素使用相同的样式规范
7. **简化样式写法**：边框、阴影等使用 Arco 变量简化
8. **避免样式冲突**：移除重复的样式声明（如 `flex: 1` 和 `height: 100%` 同时使用）

#### ⚠️ 特殊情况说明

1. **CodeMirror 编辑器主题**
   - CodeMirror 的 `EditorView.theme()` 是 JavaScript 对象配置，不支持 CSS 变量
   - 字体大小、padding 等需要硬编码值
   - 颜色可以使用 CSS 变量（`var(--color-*)`）

2. **表格行高**
   - 表格行高（如 `height: 28px`, `height: 32px`）是设计决策，保留硬编码
   - 这些值是为了紧凑显示而设计的特定值

3. **分隔条尺寸**
   - 分隔条高度（`4px`, `6px`）是交互设计的特定值，保留硬编码
   - 按钮尺寸（`30px`, `15px`）是特定交互元素的设计值

4. **最小高度限制**
   - `min-height: 150px` 等是为了确保可用性而设置的最小值
   - 这些是功能性的设计决策，不是样式规范问题

### 关键实现要点

#### 1. Tab 内容高度计算
- ✅ `.arco-tabs-content-item` 必须使用 `height: 100%` 和 `display: flex`
- ✅ Tab Content 使用 `height: 100%` 而非 `flex: 1`
- ✅ 滚动容器设置在内容层，外层容器 `overflow: hidden`

#### 2. 编辑器/结果区域调整
- ✅ 使用百分比高度存储用户偏好
- ✅ 支持拖拽调整和显示/隐藏
- ✅ 调整结果保存到 localStorage

#### 3. 滚动条处理
- ✅ 表格使用 Arco Table 的 `scroll.y` 属性
- ✅ 列表/内容区域使用 `overflow-y: auto`
- ✅ 统一滚动条样式

### 实施建议
1. **渐进式优化**：逐步替换剩余的硬编码值
2. **保持一致性**：遵循统一的样式规范
3. **测试验证**：在不同主题和屏幕尺寸下测试
4. **文档维护**：及时更新设计文档以反映实际实现

### 已知限制
- 侧边栏宽度固定为 280px，暂不支持调整
- 暂不支持响应式布局（移动端适配）
- 暂不支持布局模式预设切换（如 1:1、编辑器聚焦等）