分隔器
Alpha<script setup lang="ts">
import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'radix-vue'
</script>
<template>
<div class="w-full h-64 px-8 text-green9 font-medium text-sm">
<SplitterGroup
id="splitter-group-1"
direction="horizontal"
>
<SplitterPanel
id="splitter-group-1-panel-1"
:min-size="20"
class="bg-white rounded-xl flex items-center justify-center"
>
Panel A
</SplitterPanel>
<SplitterResizeHandle
id="splitter-group-1-resize-handle-1"
class="w-2"
/>
<SplitterPanel
id="splitter-group-1-panel-2"
:min-size="20"
>
<SplitterGroup
id="splitter-group-2"
direction="vertical"
>
<SplitterPanel
id="splitter-group-2-panel-1"
:min-size="20"
class="bg-white rounded-xl flex items-center justify-center"
>
Panel B
</SplitterPanel>
<SplitterResizeHandle
id="splitter-group-2-resize-handle-1"
class="h-2"
/>
<SplitterPanel
id="splitter-group-2-panel-2"
:min-size="20"
class="bg-white rounded-xl flex items-center justify-center"
>
Panel C
</SplitterPanel>
</SplitterGroup>
</SplitterPanel>
</SplitterGroup>
</div>
</template>
版权
此组件的设计灵感很大程度上来自于 react-resizable-panels,由 Bryan Vaughn 创建。
功能
- 支持键盘交互。
- 支持水平/垂直布局。
- 支持嵌套布局。
- 支持从右到左方向。
- 可以跨面板调整大小。
- 可以有条件地挂载。
安装
从命令行安装组件。
$ npm add radix-vue
剖析
导入所有部分并将它们拼凑在一起。
<script setup>
import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'radix-vue'
</script>
<template>
<SplitterGroup>
<SplitterPanel />
<SplitterResizeHandle />
</SplitterGroup>
</template>
API 参考
组
包含分隔器的所有部分。
道具 | 默认值 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
autoSaveId | null | 字符串 | null 用于通过 |
direction* | 'vertical' | 'horizontal' 分隔器的组方向。 | |
id | 字符串 | null 组 ID;在未提供时回退到 | |
keyboardResizeBy | 10 | 数字 | null 按下箭头键时的步长。 |
storage | defaultStorage | PanelGroupStorage 自定义存储 API;默认为 localStorage |
发出 | 有效载荷 |
---|---|
layout | [val: 数字[]] 当组布局更改时调用的事件处理程序 |
插槽 (默认) | 有效载荷 |
---|---|
layout | 数字[] 布局的当前大小 |
数据属性 | 值 |
---|---|
[data-orientation] | "vertical" | "horizontal" |
[data-state] | "collapsed" | "expanded" | "当可折叠时存在" |
面板
一个可折叠的区域。
道具 | 默认值 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
collapsedSize | 数字 面板折叠时的尺寸。 | |
collapsible | 布尔值 当调整大小超过其 | |
defaultSize | 数字 面板的初始大小(介于 1-100 之间的数值) | |
id | 字符串 面板 ID(在组内唯一);在未提供时回退到 | |
maxSize | 数字 面板的最大允许大小(介于 1-100 之间的数值);默认为 | |
minSize | 数字 面板的最小允许大小(介于 1-100 之间的数值);默认为 | |
order | 数字 面板在组内的顺序;对于具有条件渲染的面板的组来说是必需的 |
发出 | 有效载荷 |
---|---|
collapse | [] 当面板折叠时调用的事件处理程序。 |
expand | [] 当面板展开时调用的事件处理程序。 |
resize | [size: 数字, prevSize: 数字] 当面板调整大小时调用的事件处理程序;size 参数是介于 1-100 之间的数值。 |
插槽 (默认) | 有效载荷 |
---|---|
isCollapsed | 布尔值 面板是否已折叠 |
isExpanded | 布尔值 面板是否已展开 |
方法 | 类型 |
---|---|
collapse | () => void 如果面板是 |
expand | () => void 如果面板当前已折叠,则将其展开到其最近的大小。 |
getSize | () => 数字 获取面板的当前大小,以百分比表示(1 - 100)。 |
resize | (size: 数字) => void 将面板调整到指定的百分比(1 - 100)。 |
调整大小手柄
用于调整大小的手柄。
道具 | 默认值 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染成的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
disabled | 布尔值 禁用拖动手柄 | |
hitAreaMargins | PointerHitAreaMargins 在确定可调整大小手柄的命中检测时允许的边距 | |
id | 字符串 调整大小手柄 ID(在组内唯一);在未提供时回退到 | |
tabindex | 0 | 数字 手柄的 tab 索引 |
发出 | 有效载荷 |
---|---|
dragging | [isDragging: 布尔值] 在拖动手柄时调用的事件处理程序。 |
数据属性 | 值 |
---|---|
[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 持久保存布局
默认情况下,分隔器使用 localStorage
来持久保存布局。使用服务器端渲染时,这会导致当默认布局(在服务器上渲染)被持久布局(在 localStorage
中)替换时出现闪烁。避免这种闪烁的方法是使用 cookie 持久保存布局,如下所示:
<!-- with 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
分隔器组件严重依赖于唯一的 id
,但是对于 Vue<3.4,我们没有可靠的方法来生成 对 SSR 友好的 id
。
因此,如果您使用的是 Nuxt 或其他 SSR 框架,则需要为所有分隔器组件手动添加 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>
无障碍性
键盘交互
按键 | 描述 |
---|---|
Enter | 如果主窗格未折叠,则折叠窗格。如果窗格已折叠,则将分隔器恢复到其先前的位置。 |
ArrowDown | 将水平分隔器向下移动。 |
ArrowUp | 将水平分隔器向上移动。 |
ArrowRight | 将垂直分隔器向右移动。 |
ArrowLeft | 将垂直分隔器向左移动。 |
Home | 将分隔器移动到为主要窗格提供其最小允许大小的位置。 |
End | 将分隔器移动到为主要窗格提供其最大允许大小的位置。 |