Splitter
特性
- 支持键盘交互。
- 支持水平/垂直布局。
- 支持嵌套布局。
- 支持从右到左方向。
- 可跨另一面板调整大小。
- 可条件化挂载。
安装
通过命令行安装该组件。
$ npm add reka-ui结构
导入所有部件并组合在一起。
<script setup>
import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'reka-ui'
</script>
<template>
<SplitterGroup>
<SplitterPanel />
<SplitterResizeHandle />
</SplitterGroup>
</template>API 参考
Group
包含 Splitter 的所有部件。
| Prop | Default | Type |
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
autoSaveId | null | string | nullUnique id used to auto-save group arrangement via |
direction* | 'vertical' | 'horizontal'The group orientation of splitter. | |
id | string | nullGroup id; falls back to | |
keyboardResizeBy | 10 | number | nullStep size when arrow key was pressed. |
storage | defaultStorage | PanelGroupStorageCustom storage API; defaults to localStorage |
| Emit | Payload |
|---|---|
layout | [val: number[]]Event handler called when group layout changes |
| Slots (default) | Payload |
|---|---|
layout | number[]Current size of layout |
| Data Attribute | Value |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
[data-state] | "collapsed" | "expanded" | "可折叠时存在" |
Panel
可折叠的区域。
| Prop | Default | Type |
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
collapsedSize | numberThe size of panel when it is collapsed. | |
collapsible | booleanShould panel collapse when resized beyond its | |
defaultSize | numberInitial size of panel (numeric value between 1-100) | |
id | stringPanel id (unique within group); falls back to | |
maxSize | numberThe maximum allowable size of panel (numeric value between 1-100); defaults to | |
minSize | numberThe minimum allowable size of panel (numeric value between 1-100); defaults to | |
order | numberThe order of panel within group; required for groups with conditionally rendered panels |
| Emit | Payload |
|---|---|
collapse | []Event handler called when panel is collapsed. |
expand | []Event handler called when panel is expanded. |
resize | [size: number, prevSize: number]Event handler called when panel is resized; size parameter is a numeric value between 1-100. |
| Slots (default) | Payload |
|---|---|
isCollapsed | booleanIs the panel collapsed |
isExpanded | booleanIs the panel expanded |
collapse | (): voidIf panel is |
expand | (): voidIf panel is currently collapsed, expand it to its most recent size. |
resize | (size: number): voidResize panel to the specified percentage (1 - 100). |
| Methods | Type |
|---|---|
collapse | () => voidIf panel is |
expand | () => voidIf panel is currently collapsed, expand it to its most recent size. |
getSize | () => numberGets the current size of the panel as a percentage (1 - 100). |
resize | (size: number) => voidResize panel to the specified percentage (1 - 100). |
Resize Handle
用于调整大小的手柄。
| Prop | Default | Type |
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
disabled | booleanDisable drag handle | |
hitAreaMargins | PointerHitAreaMarginsAllow this much margin when determining resizable handle hit detection | |
id | stringResize handle id (unique within group); falls back to | |
nonce | stringWill add | |
tabindex | 0 | numberTabindex for the handle |
| Emit | Payload |
|---|---|
dragging | [isDragging: boolean]Event handler called when dragging the handler. |
| Data Attribute | Value |
|---|---|
[data-state] | "drag" | "hover" | "inactive" |
[data-disabled] | 禁用时存在 |
[data-orientation] | "vertical" | "horizontal" |
示例
可折叠
使用 collapsible 属性,允许面板在达到 minSize 时折叠至 collapsedSize。
(需要 collapsedSize 和 minSize 属性。)
<template>
<SplitterGroup>
<SplitterPanel
collapsible
:collapsed-size="10"
:min-size="35"
>
Panel A
</SplitterPanel>
<SplitterResizeHandle />
<SplitterPanel>
Panel B
</SplitterPanel>
</SplitterGroup>
</template>持久化到 localStorage
使用 autoSaveId 属性将布局数据保存到 localStorage。
<template>
<SplitterGroup auto-save-id="any-id">
…
</SplitterGroup>
</template>SSR 下的布局持久化
默认情况下,Splitter 使用 localStorage 来持久化布局。在服务器渲染时,当默认布局(在服务器上渲染)被持久化布局(在 localStorage 中)替换时,可能会导致闪烁。避免这种闪烁的方法是同时使用 cookie 来持久化布局,如下所示:
<!-- 使用 Nuxt -->
<script setup lang="ts">
const layout = useCookie<number[]>('splitter:layout')
</script>
<template>
<SplitterGroup
direction="horizontal"
@layout="layout = $event"
>
<SplitterPanel :default-size="layout[0]">
…
</SplitterPanel>
<SplitterResizeHandle />
<SplitterPanel :default-size="layout[1]">
…
</SplitterPanel>
</SplitterGroup>
</template>以编程方式折叠/展开
有时面板需要响应用户操作来调整大小或折叠/展开。SplitterPanel 提供了 collapse 和 expand 方法来实现这一点。
<script setup lang="ts">
const panelRef = ref<InstanceType<typeof SplitterPanel>>()
</script>
<template>
<button
@click="panelRef?.isCollapsed ? panelRef?.expand() : panelRef?.collapse() "
>
{{ panelRef?.isCollapsed ? 'Expand' : 'Collapse' }}
</button>
<SplitterGroup>
<SplitterPanel
ref="panelRef"
collapsible
:collapsed-size="10"
:min-size="35"
>
…
</SplitterPanel>
<SplitterResizeHandle />
<SplitterPanel>
…
</SplitterPanel>
</SplitterGroup>
</template>自定义手柄
通过传递任意元素作为插槽来自定义手柄。
<template>
<SplitterGroup>
<SplitterPanel>
…
</SplitterPanel>
<SplitterResizeHandle>
<Icon icon="radix-icons-drag-handle-dots-2" />
</SplitterResizeHandle>
<SplitterPanel>
…
</SplitterPanel>
</SplitterGroup>
</template>SSR
Splitter 组件严重依赖唯一的 id,然而对于 Vue<3.4,我们没有可靠的方法来生成 SSR友好的 id。
因此,如果您使用 Nuxt 或其他 SSR 框架,您需要手动为所有 Splitter 组件添加 id。或者,您可以将组件用 <ClientOnly> 包装。
<template>
<SplitterGroup id="group-1">
<SplitterPanel id="group-1-panel-1">
…
</SplitterPanel>
<SplitterResizeHandle id="group-1-resize-1">
<Icon icon="radix-icons-drag-handle-dots-2" />
</SplitterResizeHandle>
<SplitterPanel id="group-1-panel-2">
…
</SplitterPanel>
</SplitterGroup>
</template>可访问性
键盘交互
| Key | Description |
|---|---|
Enter | 如果主窗格未折叠,则折叠该窗格。如果窗格已折叠,则将分割器恢复到其先前位置。 |
ArrowDown | 将水平分割器向下移动。 |
ArrowUp | 将水平分割器向上移动。 |
ArrowRight | 将垂直分割器向右移动。 |
ArrowLeft | 将垂直分割器向左移动。 |
Home | 将分割器移动到使主窗格具有其最小允许尺寸的位置。 |
End | 将分割器移动到使主窗格具有其最大允许尺寸的位置。 |
