分割面板 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 | 是否启用延迟更新 | Boolean | — | false |
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 | 当前面板是否允许拖拽调整 | Boolean | true |
| collapsible | 是否显示折叠能力,可传布尔值或方向对象 | Boolean / { start?: boolean; end?: boolean } | false |
SplitPanel Events
| 事件名 | 说明 | 返回值 |
|---|---|---|
| update:size | 面板大小变化时触发 | (size: string | number) |
SplitPanel Slots
| 名称 | 说明 |
|---|---|
| default | 面板默认内容 |
| start-collapsible | 起始侧折叠按钮内容 |
| end-collapsible | 结束侧折叠按钮内容 |