Skip to content

分割面板 Split

分割面板用于将容器划分为多个可拖拽调整大小的区域,支持水平、垂直、折叠与延迟更新等布局场景。

基础用法

不传 size 时,剩余空间会在未指定大小的面板之间自动分配。

导航区域
内容区域
<template>
  <b-split class="split-demo">
    <b-split-panel size="30%">
      <div class="split-panel is-soft">导航区域</div>
    </b-split-panel>
    <b-split-panel :min="220">
      <div class="split-panel is-warm">内容区域</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

垂直布局

通过 layout="vertical" 切换为上下布局。

顶部信息
底部区域
<template>
  <b-split class="split-demo" layout="vertical">
    <b-split-panel size="38%">
      <div class="split-panel is-soft">顶部信息</div>
    </b-split-panel>
    <b-split-panel :min="120">
      <div class="split-panel is-cool">底部区域</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(180deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(180deg, #f3fbf8 0%, #e7f7f1 100%);
}
</style>

折叠面板

为面板设置 collapsible 后,可通过分隔条两侧的折叠按钮快速收起或恢复区域。

目录
编辑区
预览区
<template>
  <b-split class="split-demo">
    <b-split-panel size="180" collapsible min="80">
      <div class="split-panel is-soft">目录</div>
    </b-split-panel>
    <b-split-panel collapsible>
      <div class="split-panel is-cool">编辑区</div>
    </b-split-panel>
    <b-split-panel size="24%">
      <div class="split-panel is-warm">预览区</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

面板大小

size 支持数字、px 或百分比,也可以通过 v-model:size 获取当前面板大小。

资源面板
160px
工作区
<template>
  <b-split class="split-demo" @resize-end="handleResizeEnd">
    <b-split-panel>
      <div class="split-panel is-soft">资源面板</div>
    </b-split-panel>
    <b-split-panel v-model:size="size" :min="120" :max="240">
      <div class="split-panel is-cool">{{ size }}px</div>
    </b-split-panel>
    <b-split-panel>
      <div class="split-panel is-warm">工作区</div>
    </b-split-panel>
  </b-split>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const size = ref(160)

const handleResizeEnd = (_index: number, sizes: number[]) => {
  size.value = Math.round(sizes[1] || 0)
}
</script>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

延迟更新

开启 lazy 后,拖拽过程中只移动分隔条,面板尺寸会在拖拽结束后统一提交。

拖拽结束前,中间面板数值不会立即更新。

侧栏
当前宽度:180px
详情
<template>
  <div>
    <p class="split-tip">拖拽结束前,中间面板数值不会立即更新。</p>
    <b-split class="split-demo" lazy>
      <b-split-panel size="25%" collapsible>
        <div class="split-panel is-soft">侧栏</div>
      </b-split-panel>
      <b-split-panel v-model:size="size" :min="120">
        <div class="split-panel is-cool">当前宽度:{{ size }}px</div>
      </b-split-panel>
      <b-split-panel collapsible>
        <div class="split-panel is-warm">详情</div>
      </b-split-panel>
    </b-split>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const size = ref(180)
</script>

<style scoped>
.split-tip {
  margin-bottom: 10px;
  color: #5b6b88;
}

.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

禁用拖拽

当相邻任一面板设置 resizable="false" 时,该分隔条将不可拖拽。

可调整
固定宽度
内容区
<template>
  <b-split class="split-demo">
    <b-split-panel size="28%">
      <div class="split-panel is-soft">可调整</div>
    </b-split-panel>
    <b-split-panel :resizable="false" size="180">
      <div class="split-panel is-cool">固定宽度</div>
    </b-split-panel>
    <b-split-panel>
      <div class="split-panel is-warm">内容区</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}
</style>

多面板

分割面板支持两个以上的区域组合使用。

A
B
C
D
<template>
  <b-split class="split-demo">
    <b-split-panel size="18%">
      <div class="split-panel is-soft">A</div>
    </b-split-panel>
    <b-split-panel size="22%" collapsible>
      <div class="split-panel is-cool">B</div>
    </b-split-panel>
    <b-split-panel :min="140">
      <div class="split-panel is-warm">C</div>
    </b-split-panel>
    <b-split-panel size="20%">
      <div class="split-panel is-deep">D</div>
    </b-split-panel>
  </b-split>
</template>

<style scoped>
.split-demo {
  height: 280px;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  background: #fff;
}

.split-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 600;
  color: #31415c;
}

.split-panel.is-soft {
  background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%);
}

.split-panel.is-cool {
  background: linear-gradient(135deg, #f3fbf8 0%, #e7f7f1 100%);
}

.split-panel.is-warm {
  background: linear-gradient(135deg, #fffaf2 0%, #fff3df 100%);
}

.split-panel.is-deep {
  background: linear-gradient(135deg, #f6f3ff 0%, #ece7ff 100%);
}
</style>

Split Props

参数说明类型可选值默认值
layout面板布局方向String'horizontal' | 'vertical'horizontal
lazy是否启用延迟更新Booleanfalse

Split Events

事件名说明返回值
resize-start开始拖拽分隔条时触发(index: number, sizes: number[])
resize拖拽过程中触发(index: number, sizes: number[])
resize-end结束拖拽分隔条时触发(index: number, sizes: number[])
collapse点击折叠按钮时触发(index: number, type: 'start' | 'end', sizes: number[])

SplitPanel Props

参数说明类型默认值
size面板大小,支持数字、px、百分比String / Number
min面板最小尺寸,支持数字、px、百分比String / Number
max面板最大尺寸,支持数字、px、百分比String / Number
resizable当前面板是否允许拖拽调整Booleantrue
collapsible是否显示折叠能力,可传布尔值或方向对象Boolean / { start?: boolean; end?: boolean }false

SplitPanel Events

事件名说明返回值
update:size面板大小变化时触发(size: string | number)

SplitPanel Slots

名称说明
default面板默认内容
start-collapsible起始侧折叠按钮内容
end-collapsible结束侧折叠按钮内容