nex_design/docs/components/SplitLayout.md

448 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# SplitLayout 组件
## 组件说明
主内容区布局组件,支持横向(左右)和纵向(上下)两种分栏模式。用于将页面划分为主内容区和扩展信息区,支持响应式设计和灵活的布局配置。
## 组件位置
```
src/components/SplitLayout/SplitLayout.jsx
src/components/SplitLayout/SplitLayout.css
```
## 参数说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| direction | string | 否 | 'horizontal' | 布局方向:'horizontal'(左右分栏)\| 'vertical'(上下分栏) |
| mainContent | ReactNode | 是 | - | 主内容区 |
| extendContent | ReactNode | 否 | - | 扩展内容区 |
| extendSize | number | 否 | 360 | 扩展区尺寸horizontal 模式下为宽度px |
| gap | number | 否 | 16 | 主内容与扩展区间距px |
| showExtend | boolean | 否 | true | 是否显示扩展区 |
| extendPosition | string | 否 | 根据 direction 自动设置 | 扩展区位置horizontal 模式默认 'right'vertical 模式默认 'top' |
| className | string | 否 | '' | 自定义类名 |
## 布局模式
### 横向布局Horizontal
左右分栏,主内容在左,扩展信息在右。
**布局结构**
```
┌──────────────────────────┬──────────────────┐
│ │ │
│ Main Content │ Extend Info │
│ (flex: 1) │ (固定宽度) │
│ │ (可独立滚动) │
│ │ │
└──────────────────────────┴──────────────────┘
```
**适用场景**
- 数据列表 + 统计信息面板
- 监控页面 + 实时数据面板
- 表单编辑 + 帮助文档
### 纵向布局Vertical
上下分栏,扩展信息在上,主内容在下。
**布局结构**
```
┌─────────────────────────────────────────┐
│ Extend Info (高度自适应, 可收起) │
├─────────────────────────────────────────┤
│ │
│ Main Content │
│ │
│ │
└─────────────────────────────────────────┘
```
**适用场景**
- 带统计面板的列表页
- 可展开/收起的筛选条件区
- 概览信息 + 详细列表
## 使用示例
### 基础用法 - 横向布局
```jsx
import SplitLayout from '../components/SplitLayout/SplitLayout'
import ListTable from '../components/ListTable/ListTable'
import ExtendInfoPanel from '../components/ExtendInfoPanel/ExtendInfoPanel'
function MyPage() {
return (
<SplitLayout
direction="horizontal"
mainContent={
<ListTable columns={columns} dataSource={data} />
}
extendContent={
<ExtendInfoPanel sections={sections} />
}
/>
)
}
```
### 纵向布局 + 可折叠
```jsx
import { useState } from 'react'
import PageTitleBar from '../components/PageTitleBar/PageTitleBar'
import SplitLayout from '../components/SplitLayout/SplitLayout'
import ExtendInfoPanel from '../components/ExtendInfoPanel/ExtendInfoPanel'
function MyPage() {
const [showStats, setShowStats] = useState(false)
return (
<>
<PageTitleBar
title="用户列表"
showToggle={true}
defaultExpanded={false}
onToggle={setShowStats}
/>
<SplitLayout
direction="vertical"
mainContent={
<>
<ListActionBar ... />
<ListTable ... />
</>
}
extendContent={
<ExtendInfoPanel
layout="horizontal"
sections={[
{
key: 'stats',
title: '数据统计',
content: <StatCards />
}
]}
/>
}
showExtend={showStats}
/>
</>
)
}
```
### 自定义尺寸和间距
```jsx
<SplitLayout
direction="horizontal"
mainContent={<div>主内容</div>}
extendContent={<div>扩展信息</div>}
extendSize={400}
gap={24}
/>
```
### 完整示例 - 虚拟机镜像页面
```jsx
import { useState } from 'react'
import SplitLayout from '../components/SplitLayout/SplitLayout'
import ListActionBar from '../components/ListActionBar/ListActionBar'
import ListTable from '../components/ListTable/ListTable'
import ExtendInfoPanel from '../components/ExtendInfoPanel/ExtendInfoPanel'
import StatCard from '../components/StatCard/StatCard'
import ChartPanel from '../components/ChartPanel/ChartPanel'
function VirtualMachineImagePage() {
const [selectedRowKeys, setSelectedRowKeys] = useState([])
return (
<SplitLayout
direction="horizontal"
mainContent={
<>
<ListActionBar
actions={[
{ key: 'add', label: '新建镜像', type: 'primary' },
{ key: 'delete', label: '批量删除', danger: true },
]}
search={{ placeholder: '搜索镜像' }}
/>
<ListTable
columns={columns}
dataSource={data}
selectedRowKeys={selectedRowKeys}
onSelectionChange={setSelectedRowKeys}
/>
</>
}
extendContent={
<ExtendInfoPanel
sections={[
{
key: 'overview',
title: '概览',
content: (
<div style={{ display: 'grid', gap: '12px' }}>
<StatCard
key="total"
title="镜像总数"
value={32}
icon={<DatabaseOutlined />}
color="blue"
gridColumn="1 / -1"
/>
<StatCard
key="running"
title="运行中"
value={28}
color="green"
/>
<StatCard
key="stopped"
title="已停止"
value={4}
color="gray"
/>
</div>
),
},
{
key: 'charts',
title: '性能监控',
content: (
<>
<ChartPanel
type="line"
title="CPU使用率趋势"
data={cpuData}
height={180}
/>
<ChartPanel
type="line"
title="内存使用率趋势"
data={memoryData}
height={180}
/>
</>
),
},
]}
/>
}
extendSize={360}
extendPosition="right"
/>
)
}
```
## DOM 结构
### 横向布局
```html
<div class="split-layout split-layout-horizontal" style="gap: 16px">
<!-- 主内容区 -->
<div class="split-layout-main">
{mainContent}
</div>
<!-- 扩展信息区 -->
<div class="split-layout-extend split-layout-extend-right" style="width: 360px">
{extendContent}
</div>
</div>
```
### 纵向布局
```html
<div class="split-layout split-layout-vertical" style="gap: 16px">
<!-- 扩展信息区 -->
<div class="split-layout-extend split-layout-extend-top">
{extendContent}
</div>
<!-- 主内容区 -->
<div class="split-layout-main">
{mainContent}
</div>
</div>
```
## 响应式设计
### 横向布局响应式
| 屏幕宽度 | 布局行为 |
|---------|---------|
| ≥ 1200px | 显示扩展信息区 |
| < 1200px | 自动隐藏扩展信息区 |
```css
@media (max-width: 1200px) {
.split-layout-extend-right {
display: none;
}
}
```
### 纵向布局响应式
- 扩展区始终占满宽度
- 高度由内容自适应
- 通过 `showExtend` 参数控制显示/隐藏
## 样式定制
组件提供以下 CSS 类名供自定义样式:
- `.split-layout` - 布局容器
- `.split-layout-horizontal` - 横向布局模式
- `.split-layout-vertical` - 纵向布局模式
- `.split-layout-main` - 主内容区
- `.split-layout-extend` - 扩展信息区
- `.split-layout-extend-right` - 右侧扩展区(横向布局)
- `.split-layout-extend-top` - 顶部扩展区(纵向布局)
### 自定义样式示例
```css
/* 修改扩展区背景色 */
.split-layout-extend {
background: #f5f5f5;
}
/* 自定义滚动条样式(横向布局) */
.split-layout-extend-right::-webkit-scrollbar {
width: 8px;
}
.split-layout-extend-right::-webkit-scrollbar-thumb {
background: #1677ff;
border-radius: 4px;
}
```
## 使用场景
### 1. 横向布局场景
- **数据列表 + 信息面板**:左侧显示数据表格,右侧显示统计信息和图表
- **监控页面**:左侧显示设备列表,右侧显示实时监控数据
- **内容编辑 + 预览**:左侧编辑器,右侧实时预览
### 2. 纵向布局场景
- **带统计面板的列表页**:顶部显示统计卡片,下方显示数据列表
- **可展开的筛选区**:顶部显示筛选条件,下方显示筛选结果
- **概览信息页**:顶部显示关键指标,下方显示详细数据
## 注意事项
### 1. 横向布局
- **扩展区宽度建议**320-400px
- **主内容最小宽度**:确保至少 800px
- **总宽度建议**:≥ 1200px
- **扩展区滚动**:自动 sticky 定位,独立滚动
### 2. 纵向布局
- **扩展区高度**:由内容自适应,不需要设置固定高度
- **配合 PageTitleBar**:使用 toggle 功能控制显示/隐藏
- **内容组织**:避免扩展区内容过多,建议不超过 300px 高度
### 3. 内容组织
- **主内容区**:放置主要内容(列表、表格、表单等)
- **扩展区**:放置辅助信息(统计、图表、说明等)
- **避免**:扩展区放置过多交互元素
### 4. 性能考虑
- 扩展区内容会始终渲染(即使隐藏)
- 如需完全卸载,使用 `showExtend={false}`
- 大量图表建议使用懒加载
### 5. 布局选择
```jsx
// ✅ 适合横向布局
- 需要持续展示的监控信息
- 辅助信息较多且重要
- 页面宽度充足> 1200px
// ✅ 适合纵向布局
- 统计信息可按需展开
- 移动端友好的布局
- 扩展内容简洁明了
// ❌ 不需要 SplitLayout
- 简单的列表页面
- 无扩展信息需求
- 直接使用 ListActionBar + ListTable
```
## 迁移指南
### 从旧版 API 迁移
**旧版代码**
```jsx
<SplitLayout
leftContent={<Content />}
rightContent={<SideInfoPanel sections={...} />}
rightWidth={360}
showRight={true}
/>
```
**新版代码**
```jsx
<SplitLayout
direction="horizontal"
mainContent={<Content />}
extendContent={<ExtendInfoPanel sections={...} />}
extendSize={360}
showExtend={true}
extendPosition="right"
/>
```
**变更对照表**
| 旧参数 | 新参数 | 说明 |
|--------|--------|------|
| leftContent | mainContent | 主内容区 |
| rightContent | extendContent | 扩展内容区 |
| rightWidth | extendSize | 扩展区尺寸 |
| showRight | showExtend | 显示扩展区 |
| - | direction | 新增:布局方向 |
| - | extendPosition | 新增:扩展区位置 |
## 配合使用的组件
- **ExtendInfoPanel** - 扩展信息面板容器(推荐)
- **StatCard** - 统计卡片
- **ChartPanel** - 图表展示
- **ListTable** - 列表表格
- **ListActionBar** - 列表操作栏
- **PageTitleBar** - 页面标题栏(配合纵向布局)
## 相关文档
- [主内容区布局](../layouts/content-area-layout.md) - 详细的布局使用指南
- [ExtendInfoPanel](./ExtendInfoPanel.md) - 扩展信息面板组件
- [StatCard](./StatCard.md) - 统计卡片组件
- [ChartPanel](./ChartPanel.md) - 图表面板组件