Preview Updated 2026-05-10

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.

背景

侧栏

当前宽度:35%。拖动中间分隔条调整。

主区域

键盘可用:聚焦分隔条后 ←→ 微调,Shift+←→ 跳大步,Home/End 直接到极值。

src/App.vue
<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>
<script setup>
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.

背景
编辑器
function hello() {
  return 'hi';
}
控制台
> hi
src/App.vue
<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;">
            &gt; hi
          </div>
        </div>
      </template>
    </CfSplitter>
  </div>
</template>
<script setup>
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;">
            &gt; hi
          </div>
        </div>
      </template>
    </CfSplitter>
  </div>
</template>
import { useState } from 'react';
import { CfSplitter } from '@chufix-design/react';

export default function Demo() {
  const [size, setSize] = useState(50);
  return (
    <>
      <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).

背景
侧栏 — 当前 220px
主区域
src/App.vue
<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>
<script setup>
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>
import { useState } from 'react';
import { CfSplitter } from '@chufix-design/react';

export default function Demo() {
  const [size, setSize] = useState(220);
  return (
    <>
      <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.

背景
禁用 — 无法拖拽
分隔条仅作展示
src/App.vue
<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>
<script setup>
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>
import { CfSplitter } from '@chufix-design/react';

export default function Demo() {
  const size = 40;
  return (
    <>
      <CfSplitter value={size} disabled />
    </>
  );
}

API

PropTypeDefaultDescription
modelValue (Vue) / value (React)numberControlled size value; omit to self-manage with defaultSize
defaultSize (Vue) / defaultValue (React)number30Initial size
unit'%' | 'px''%'Value unit
orientation'horizontal' | 'vertical''horizontal'Layout direction
min / maxnumber10 / 90Value bounds (matching unit)
disabledbooleanfalseDisable dragging
collapsiblebooleanfalseEnable 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

0
0 / 600
一键发送
正在加载评论...