SegmentedButtons 分段按钮
由 SegmentedButtons 与 SegmentedButton 组合而成:父组件持有选中值(v-model:value), 每个 SegmentedButton 描述一个分段。默认是单选控件——选中项不能被取消选中;加上 multiple 后变成一组可独立切换的按钮(v-model:value 是数组)。
- 所有分段平分父组件宽度,与文字长短无关。
- 分段标识默认为自身索引,也可以用
value指定。 - 未选中时用
icon显示前置图标;选中后固定显示勾选图标。
基础用法
当前选中值:day
vue
<script setup lang="ts">
import { ref } from "vue";
import { SegmentedButton, SegmentedButtons } from "@sharpdotnut/dotsharp";
const period = ref("day");
</script>
<template>
<SegmentedButtons v-model:value="period">
<SegmentedButton label="每日" value="day" />
<SegmentedButton label="每周" value="week" />
<SegmentedButton label="每月" value="month" />
</SegmentedButtons>
</template>标识:value 与索引
省略 value 时,分段用声明顺序的索引(从 0 开始)作为标识;v-model:value 默认是 0, 因此首个分段默认选中。
当前选中索引:0
vue
<script setup lang="ts">
import { ref } from "vue";
import { SegmentedButton, SegmentedButtons } from "@sharpdotnut/dotsharp";
const index = ref(0);
</script>
<template>
<SegmentedButtons v-model:value="index">
<SegmentedButton label="日" />
<SegmentedButton label="周" />
<SegmentedButton label="月" />
</SegmentedButtons>
</template>多选
multiple 打开后,模型是标识数组,点击分段切换它自己的选中态;一个都不选、全选都合法。
当前选中:mon、fri
vue
<script setup lang="ts">
import { ref } from "vue";
import { SegmentedButton, SegmentedButtons } from "@sharpdotnut/dotsharp";
const days = ref<Array<string | number>>(["mon", "fri"]);
</script>
<template>
<SegmentedButtons v-model:value="days" multiple>
<SegmentedButton label="周一" value="mon" />
<SegmentedButton label="周三" value="wed" />
<SegmentedButton label="周五" value="fri" />
</SegmentedButtons>
</template>图标
未选中时渲染 icon;选中后该位置换成勾选图标,用来强调当前状态。需要不受 1.25em 限制的图标时,改用默认插槽配合 <Icon size="…">。
vue
<script setup lang="ts">
import { ref } from "vue";
import { SegmentedButton, SegmentedButtons } from "@sharpdotnut/dotsharp";
import calendarIcon from "@iconify-icons/material-symbols/calendar-today";
import homeIcon from "@iconify-icons/material-symbols/home";
import wifiIcon from "@iconify-icons/material-symbols/wifi";
const place = ref("home");
</script>
<template>
<SegmentedButtons v-model:value="place">
<SegmentedButton label="首页" value="home" :icon="homeIcon" />
<SegmentedButton label="日程" value="calendar" :icon="calendarIcon" />
<SegmentedButton label="网络" value="wifi" :icon="wifiIcon" />
</SegmentedButtons>
</template>禁用
禁用的分段不可点击、不可聚焦,也不参与方向键移动。
vue
<SegmentedButtons v-model:value="period">
<SegmentedButton label="每日" value="day" />
<SegmentedButton label="每周" value="week" />
<SegmentedButton label="每月" value="month" disabled />
</SegmentedButtons>键盘操作
分段组使用 roving tabindex:整组只有一个分段是 tabindex="0",其余为 -1。
←/→:在可用分段之间移动焦点,首尾循环;RTL 方向自动对调。Home/End:跳到第一个 / 最后一个可用分段。
单选时方向键移动焦点会立即选中,与单选组的行为一致;多选时方向键只移动焦点, 必须按回车 / 空格才会切换选中态——否则移动焦点就会把已有选择清掉。Tab 键正常离开整组。
API
SegmentedButtons
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model:value | string | number | (string | number)[] | 0 | 当前选中值,对应子项的 value 或索引;多选时是数组 |
| multiple | boolean | false | 多选:点击切换各分段,模型改为标识数组 |
根元素是 role="group" 的 div,其余属性与事件透传到该元素。
SegmentedButton
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | string | — | 纯文本内容;存在默认插槽时被插槽覆盖 |
| icon | IconifyIcon | string | — | 未选中时的前置图标,尺寸 1.25em 跟随字号 |
| value | string | number | 所在位置索引 | 分段标识 |
| disabled | boolean | false | 禁用:不可聚焦、不参与方向键移动、点击不选中 |
- 根元素是原生
button,带aria-pressed,其余属性与事件透传到该按钮。 - 点击已选中的分段不会重复写模型,也不会触发
update:value。
可访问性
组根元素是 role="group",每个分段是原生 button 并带 aria-pressed,因此读屏会把整组理解为一组切换按钮。 键盘遵循 roving tabindex:只有当前焦点分段可被 Tab 到达,方向键在 button:not([disabled]) 之间移动, Home / End 跳到两端。