--- title: Splitter 分割面板 description: 可拖拽调整大小的多面板布局,支持左右 / 上下与嵌套 --- # Splitter 分割面板 `Splitter` 把容器切成若干可拖拽调整大小的面板,用于 IDE 式布局:侧栏 + 编辑区 + 控制台。 ## 何时使用 - 用户需要自己决定「哪一块看多少」时(列表 / 详情、代码 / 预览); - 页面结构固定且各区域可独立滚动时; - 只是把内容分列、用户不需要调整时,用 [Grid](/ui/general/grid) 更轻。 ## 基础用法 `G3SplitterPanel` 放 `G3Splitter` 内。给了 `defaultSize` / `size` 的面板尺寸固定,其余面板平分剩余空间。 ## 上下分栏 `direction="vertical"` 时用 `defaultSize` 控制高度;`barOnHover` 默认 `true`(分割线只在 hover / 聚焦 / 拖拽时显示)。 ## 尺寸约束 `min` / `max` 支持数字(px)或百分比字符串;`resizable="false"` 的面板不参与拖动(两侧都必须可调,分隔条才能拖)。 ## 嵌套 外层左右、内层上下,可以组合出常见的工作台布局。 ## 键盘操作 分隔条是可聚焦的(`role="separator"`):`Tab` 聚焦后,用 `← →`(横向)或 `↑ ↓`(纵向)调整,步长 10px,按住 `Shift` 为 50px;同时会通过 `aria-valuenow / valuemin / valuemax` 播报当前位置百分比。 ## API ### Props(Splitter) | 名称 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | 分割方向。`horizontal` 为左右分栏 | | `barOnHover` | `boolean` | `true` | 分割线仅在 hover / 聚焦 / 拖拽时显示 | ### Props(SplitterPanel) | 名称 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `size` | `number \| string` | — | 受控尺寸(px 或 `'30%'`)。传入后拖拽不会由内部接管该面板 | | `defaultSize` | `number \| string` | — | 非受控初始尺寸;拖拽后由内部接管 | | `min` | `number \| string` | — | 最小尺寸,拖动时约束 | | `max` | `number \| string` | — | 最大尺寸,拖动时约束 | | `resizable` | `boolean` | `true` | 是否允许被相邻分隔条调整(两侧都为 `true` 才可拖) | ### Events(Splitter) | 名称 | 参数 | 说明 | | --- | --- | --- | | `resizeStart` | `(sizes: number[])` | 开始拖拽,参数是各面板的实测像素宽/高 | | `resize` | `(sizes: number[])` | 拖拽过程中每帧触发(键盘调整也会触发一次) | | `resizeEnd` | `(sizes: number[])` | 拖拽结束(键盘调整后同样触发) | ### Slots | 组件 | 插槽 | 说明 | | --- | --- | --- | | Splitter | `default` | `G3SplitterPanel` 列表(其他元素会被忽略) | | SplitterPanel | `default` | 面板内容 | ### 类型定义 ```ts export type SplitterDirection = 'horizontal' | 'vertical' export type SplitterSize = number | string export interface SplitterProps { direction?: SplitterDirection barOnHover?: boolean } export interface SplitterPanelProps { min?: SplitterSize max?: SplitterSize size?: SplitterSize defaultSize?: SplitterSize resizable?: boolean } ``` ### 样式变量 | 变量 | 默认值 | 说明 | | --- | --- | --- | | `--g3-splitter-trigger-size` | `10px` | 分隔条命中区宽度(比视觉线宽,方便抓取) | | `--g3-splitter-bar-size` | `3px` | 视觉线宽 | | `--g3-color-primary` | `#18181b` | 拖拽 / 聚焦时的线色 | ## 实现说明 - **尺寸模型**:只有「给了 `size` / `defaultSize` 的面板」和「刚被拖动过的相邻两块」持有明确像素值,其余面板用 `flex: 1 1 0%` 平分。拖拽结束会调用 `releaseAutoPanels()`,把没有显式尺寸的面板恢复成自动——否则窗口缩放后剩余空间会填不满; - **拖拽实现**:Pointer Events + `requestAnimationFrame` 合并(`pointermove` 只记最新事件,帧内只算一次),并且只在 `window` 上挂监听,指针移出面板也不会中断;拖动期间禁用文本选中; - **约束算法**:把偏移量先按前一格的 `[min, max]` 钳制,再按后一格的 `[min, max]` 钳制,两块面板的尺寸之和保持不变(不会把总宽拖变形); - 分隔条的 `aria-orientation` 与视觉方向**相反**(左右分栏时分隔条是纵向的 `vertical`),这是 ARIA 规范要求的语义; - 面板内容区自带 `overflow: auto`,因此面板内部滚动不会影响外层布局。