4.3 KiB
4.3 KiB
title, description
| title | description |
|---|---|
| Segmented 分段控制器 | 在一组互斥选项中切换,滑块跟随选中项移动 |
Segmented 分段控制器
分段控制器把 2-5 个互斥选项并排展示,用一个会滑动的滑块指示当前选项。它比 Tabs 轻量:切换的是同一区域的视图模式,不是内容面板。
何时使用
- 视图模式切换:列表 / 看板 / 时间线;
- 粒度切换:日 / 周 / 月;
- 表单里的少量选项(2-5 项)时,比 Select 更快、比 Radio 更紧凑;
- 选项超过 5 个、或需要多选时,请改用 Select / Checkbox。
基础用法
options 可以直接传原始值数组,选中值通过 v-model 双向绑定(支持字符串、数字、布尔)。
对象选项
选项写成对象可以自定义显示文字、加图标、单独禁用某一项。
圆角形状
纵向排列
vertical 时滑块上下移动,适合做侧边栏的视图切换。
撑满宽度
block 让各项等分父容器宽度(纵向时为高度),常用于移动端或表单顶部。
自定义每项内容
#label 插槽作用域为 { option, index, checked }:option 是原始选项对象,checked 表示该项是否选中。
非受控用法
不传 modelValue 时组件内部维护选中值(默认不选中),通过 change 把结果抛给业务。
API
Props
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue |
string | number | boolean |
— | 双向绑定的选中值。不传即非受控 |
options |
Array<SegmentedOptionInput> |
[] |
选项数据源,元素可以是原始值或 { label, value, disabled, icon } |
shape |
'default' | 'round' |
'default' |
圆角形状。round 为全圆角胶囊 |
vertical |
boolean |
false |
纵向排列,滑块上下移动 |
block |
boolean |
false |
撑满父容器并等分各项 |
disabled |
boolean |
false |
禁用整组 |
name |
string |
自动生成 | 原生 radio 组名。不传时用 useId 生成,避免多组互斥冲突 |
Events
| 名称 | 参数 | 说明 |
|---|---|---|
update:modelValue |
(value: string | number | boolean) |
选中项变化时触发(受控与非受控都会触发) |
change |
(value: string | number | boolean) |
同上,便于只监听变化 |
Slots
| 名称 | 参数 | 说明 |
|---|---|---|
label |
{ option: SegmentedOptionInput, index: number, checked: boolean } |
自定义每项内容;不传时渲染 icon + label |
类型定义
export type SegmentedValue = string | number | boolean
export interface SegmentedOption {
label?: string
value: SegmentedValue
disabled?: boolean
icon?: Component | VNode
}
export type SegmentedOptionInput = SegmentedValue | SegmentedOption
export type SegmentedShape = 'default' | 'round'
样式变量
| 变量 | 默认值 | 说明 |
|---|---|---|
--g3-segmented-padding |
2px |
轨道内边距 |
--g3-radius |
6px |
轨道圆角(round 时为全圆角) |
--g3-fill |
rgba(0,0,0,.04) |
轨道底色 |
--g3-bg-container |
#fff |
滑块底色 |
--g3-shadow |
0 2px 8px rgba(0,0,0,.15) |
滑块投影 |
实现说明
- 底层是原生 radio 组(
input[type=radio]+<label>),因此键盘方向键切换、屏幕阅读器分组语义都由浏览器原生提供; - 滑块的位移与尺寸通过
getBoundingClientRect测量并写入 CSS 变量,容器尺寸变化时用ResizeObserver重算,所以字体缩放、文案长度变化都能跟上; - 首次渲染时滑块先隐藏(
thumbVisible),测量完成后再淡入,避免从(0,0)位置滑过来的闪动; - 选项里的图标会经过
toRaw处理:options常由ref提供,直接使用会被深层响应式包装,触发 Vue 的「组件被响应式化」告警; - 与 Tabs 的区别:Segmented 没有面板,只负责"选择";Tabs 负责"选择 + 内容区 + 懒渲染"。