Splitter
Drag the divider to resize two panels — horizontal / vertical, keyboard accessible, controllable.
Basic usage
v-model binds a number. With unit="%" (default) it’s a percentage; with unit="px" it’s pixels. min / max clamp the range. After focusing the divider with the keyboard: ← / → for fine adjustment (Shift jumps by 10), Home / End jump to the extremes.
<script setup lang="ts">
import { ref } from 'vue';
import { CfSplitter } from '@chufix-design/vue';
const size = ref(35);
</script>
<template>
<div style="height: 240px; border: 1px solid var(--line-1); border-radius: 8px; overflow: hidden;">
<CfSplitter v-model="size" :min="15" :max="85">
<template #start>
<div style="padding: 16px;">
<h3 style="margin: 0 0 8px;">侧栏</h3>
<p style="margin: 0; font-size: 12px; color: var(--fg-3);">
当前宽度:{{ Math.round(size) }}%。拖动中间分隔条调整。
</p>
</div>
</template>
<template #end>
<div style="padding: 16px;">
<h3 style="margin: 0 0 8px;">主区域</h3>
<p style="margin: 0; font-size: 12px; color: var(--fg-3);">
键盘可用:聚焦分隔条后 ←→ 微调,Shift+←→ 跳大步,Home/End 直接到极值。
</p>
</div>
</template>
</CfSplitter>
</div>
</template>
import { useState } from 'react';
import { CfSplitter } from '@chufix-design/react';
export default function Demo() {
const [size, setSize] = useState(35);
return (
<CfSplitter
value={size}
min={15}
max={85}
start={<div>Sidebar</div>}
end={<div>Main</div>}
onChange={setSize}
/>
);
} Vertical
orientation="vertical" rotates the divider horizontally, splitting top and bottom panels. Common for editor + console or table + detail layouts.
<script setup lang="ts">
import { ref } from 'vue';
import { CfSplitter } from '@chufix-design/vue';
const size = ref(50);
</script>
<template>
<div style="height: 280px; border: 1px solid var(--line-1); border-radius: 8px; overflow: hidden;">
<CfSplitter
v-model="size"
orientation="vertical"
:min="20"
:max="80"
>
<template #start>
<div style="padding: 12px; height: 100%; background: var(--bg-1);">
<strong>编辑器</strong>
<pre style="margin: 8px 0 0; font-size: 12px; color: var(--fg-2);">function hello() {{ '{' }}
return 'hi';
{{ '}' }}</pre>
</div>
</template>
<template #end>
<div style="padding: 12px; height: 100%; background: var(--bg-2);">
<strong>控制台</strong>
<div style="margin-top: 8px; font-family: var(--font-mono); font-size: 12px;">
> hi
</div>
</div>
</template>
</CfSplitter>
</div>
</template>
<CfSplitter
value={size}
orientation="vertical"
min={20}
max={80}
start={<div>Editor</div>}
end={<div>Console</div>}
onChange={setSize}
/> Pixel unit
unit="px" switches the value to pixels — ideal when the sidebar width must be precise (and shouldn’t change with the viewport like % does).
<script setup lang="ts">
import { ref } from 'vue';
import { CfSplitter } from '@chufix-design/vue';
const size = ref(220);
</script>
<template>
<CfSplitter v-model="size" unit="px" :min="120" :max="480">
<template #start>
<div style="padding: 16px;">侧栏 — 当前 {{ size }}px</div>
</template>
<template #end>
<div style="padding: 16px;">主区域</div>
</template>
</CfSplitter>
</template>
<CfSplitter
value={size}
onChange={setSize}
unit="px"
min={120}
max={480}
start={<div>Sidebar — currently {size}px</div>}
end={<div>Main</div>}
/> Disabled
disabled locks the divider — the current ratio is still rendered but users can’t drag. Common in demo states or restricted-permission views.
<script setup lang="ts">
import { ref } from 'vue';
import { CfSplitter } from '@chufix-design/vue';
const size = ref(40);
</script>
<template>
<CfSplitter v-model="size" disabled>
<template #start>
<div style="padding: 16px; color: var(--fg-3);">禁用 — 无法拖拽</div>
</template>
<template #end>
<div style="padding: 16px; color: var(--fg-3);">分隔条仅作展示</div>
</template>
</CfSplitter>
</template>
<CfSplitter value={size} disabled /> API
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue (Vue) / value (React) | number | — | Controlled size value; omit to self-manage with defaultSize |
defaultSize (Vue) / defaultValue (React) | number | 30 | Initial size |
unit | '%' | 'px' | '%' | Value unit |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout direction |
min / max | number | 10 / 90 | Value bounds (matching unit) |
disabled | boolean | false | Disable dragging |
collapsible | boolean | false | Enable Enter / Space to toggle between min and defaultSize |
resizeFrom | 'start' | 'end' | 'start' | Which side the value tracks |
Events: update:modelValue / resize (React: onChange / onResize).
Slots: start / end (React uses same-named props that accept ReactNode).
反馈与讨论
Splitter · Discussion