Skip to content

Segmented 分段控件

胶囊式切换器。只管选中值,不管内容。

基础用法

vue
<script setup>
import { ref } from 'vue'

const options = [
  { label: '列表', value: 'list' },
  { label: '网格', value: 'grid' },
  { label: '表格', value: 'table' }
]

const view = ref('list')
</script>

<template>
  <SrSegmented v-model="view" :options="options" />
</template>

当前选中:list

与 Tabs 的分工

两者都是「多选一」,但职责完全不同

SrTabsSrSegmented
内容内含内容面板不管内容
数据来源子组件自动收集options 数组
样式下划线 / 卡片胶囊 + 滑动指示器
典型场景分区切换(各区块内容不同)视图模式切换、筛选条件

一句话:Tabs 自带内容,Segmented 只告诉你用户选了什么。 切换后要渲染什么,由宿主根据选中的值决定。

作为筛选条件

分段控件最常见的用法之一是配合列表筛选——它只提供值,过滤逻辑在宿主

宿主拿到 list 后自行决定如何渲染

禁用项

选项级的 disabled。禁用项仍显示在控件里—— 直接过滤掉会改变控件的宽度,用户会觉得「选项怎么少了一个」。

vue
const options = [
  { label: '可点', value: 1 },
  { label: '禁用', value: 2, disabled: true }
]

尺寸

vue
<SrSegmented size="sm" :options="options" />
<SrSegmented size="md" :options="options" />
<SrSegmented size="lg" :options="options" />

占满一行

block 让控件撑满父容器宽度,各选项等分。

vue
<SrSegmented v-model="view" :options="options" block />

整体禁用

vue
<SrSegmented disabled :options="options" />

滑动指示器

选中背景是一个绝对定位的滑块,切换时通过 transform: translateX() 平滑移动,而不是让两个选项的背景色瞬间互换。

transform 而不是 left:前者由合成器处理,不触发重排, 在列表页这类滚动场景下不会有掉帧感。

Props

名称类型默认值说明
modelValuestring | number当前选中值
options{ label, value, disabled? }[][]选项列表
size'sm' | 'md' | 'lg''md'尺寸
blockbooleanfalse是否占满一行
disabledbooleanfalse是否整体禁用

事件

事件参数说明
update:modelValue选中值选中项变化
change选中值同上(语义化事件)

无障碍

  • 容器用 role="radiogroup",每个选项 role="radio" 并带 aria-checked—— 语义上它就是「一组里选一个」,与单选按钮一致
  • 键盘:← → 在选项间移动,Home / End 跳到首尾
  • 禁用项带 aria-disabled,读屏软件会播报但不会跳过它们, 保持选项顺序的可预测性

自用组件库 · 源码分发 · 不发布 npm