Segmented 分段控制器
展示多个互斥选项,并允许用户选择其中一项。
基础用法
将 v-model 绑定到当前选中项的值。
vue
<template>
<div class="flex flex-col items-start gap-4">
<u-segmented v-model="value" :options="options" size="large" />
<u-segmented v-model="value" :options="options" size="default" />
<u-segmented v-model="value" :options="options" size="small" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Mon')
const options = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
</script>
隐藏源代码
纵向布局
设置 vertical 可改为纵向排列。
vue
<template>
<div>
<u-segmented
v-model="size"
:options="sizeOptions"
style="margin-bottom: 1rem"
/>
<br />
<u-segmented
v-model="direction"
:options="directionOptions"
style="margin-bottom: 1rem"
/>
<br />
<u-segmented
v-model="value"
:options="options"
:direction="direction"
:size="size"
>
<template #default="scope">
<div
:class="[
'flex',
'items-center',
'gap-2',
'flex-col',
direction === 'horizontal' && 'p-2',
]"
>
<u-icon size="20">
<component :is="scope.item.icon" />
</u-icon>
<div>{{ scope.item.label }}</div>
</div>
</template>
</u-segmented>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import {
Apple,
Cherry,
Grape,
Orange,
Pear,
Watermelon,
} from '@uniboot/icons-vue'
import type { SegmentedProps } from 'uniboot-ui'
const value = ref('Apple')
const direction = ref<SegmentedProps['direction']>('horizontal')
const size = ref<SegmentedProps['size']>('default')
const directionOptions = [
{ label: 'Horizontal', value: 'horizontal' },
{ label: 'Vertical', value: 'vertical' },
]
const sizeOptions = ['large', 'default', 'small']
const options = [
{
label: 'Apple',
value: 'Apple',
icon: Apple,
},
{
label: 'Cherry',
value: 'Cherry',
icon: Cherry,
},
{
label: 'Grape',
value: 'Grape',
icon: Grape,
},
{
label: 'Orange',
value: 'Orange',
icon: Orange,
},
{
label: 'Pear',
value: 'Pear',
icon: Pear,
},
{
label: 'Watermelon',
value: 'Watermelon',
icon: Watermelon,
disabled: true,
},
]
</script>
隐藏源代码
禁用
将分段控制器或某个选项的 disabled 设为 true 即可禁用。
vue
<template>
<div class="flex flex-col items-start gap-4">
<u-segmented v-model="value" :options="options" disabled />
<u-segmented v-model="value" :options="options" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Mon')
const options = [
{
label: 'Mon',
value: 'Mon',
disabled: true,
},
{
label: 'Tue',
value: 'Tue',
},
{
label: 'Wed',
value: 'Wed',
disabled: true,
},
{
label: 'Thu',
value: 'Thu',
},
{
label: 'Fri',
value: 'Fri',
disabled: true,
},
{
label: 'Sat',
value: 'Sat',
},
{
label: 'Sun',
value: 'Sun',
},
]
</script>
隐藏源代码
自定义选项字段
当 options 数据字段名与默认不一致时,可通过 props 配置别名。
vue
<template>
<div>
<u-segmented v-model="value" :options="options" :props="props" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Mon')
const props = {
label: 'myLabel',
value: 'myValue',
disabled: 'myDisabled',
}
const options = [
{
myLabel: 'Mon',
myValue: 'Mon',
myDisabled: true,
},
{
myLabel: 'Tue',
myValue: 'Tue',
},
{
myLabel: 'Wed',
myValue: 'Wed',
myDisabled: true,
},
{
myLabel: 'Thu',
myValue: 'Thu',
},
{
myLabel: 'Fri',
myValue: 'Fri',
myDisabled: true,
},
{
myLabel: 'Sat',
myValue: 'Sat',
},
{
myLabel: 'Sun',
myValue: 'Sun',
},
]
</script>
隐藏源代码
撑满宽度
将 block 设为 true 可使宽度跟随父级。
vue
<template>
<div>
<u-segmented v-model="value" :options="options" block />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Mon')
const options = [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sunday long long long long long long long',
]
</script>
隐藏源代码
自定义内容
使用默认插槽自定义每一项的展示内容。
vue
<template>
<div>
<u-segmented v-model="value" :options="options">
<template #default="scope">
<div class="flex flex-col items-center gap-2 p-2">
<u-icon size="20">
<component :is="scope.item.icon" />
</u-icon>
<div>{{ scope.item.label }}</div>
</div>
</template>
</u-segmented>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import {
Apple,
Cherry,
Grape,
Orange,
Pear,
Watermelon,
} from '@uniboot/icons-vue'
const value = ref('Apple')
const options = [
{
label: 'Apple',
value: 'Apple',
icon: Apple,
},
{
label: 'Cherry',
value: 'Cherry',
icon: Cherry,
},
{
label: 'Grape',
value: 'Grape',
icon: Grape,
},
{
label: 'Orange',
value: 'Orange',
icon: Orange,
},
{
label: 'Pear',
value: 'Pear',
icon: Pear,
},
{
label: 'Watermelon',
value: 'Watermelon',
icon: Watermelon,
},
]
</script>
隐藏源代码
自定义样式
通过 CSS 变量覆盖样式。
vue
<template>
<div class="custom-style">
<u-segmented v-model="value" :options="options" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Delicacy')
const options = ['Delicacy', 'Desserts&Drinks', 'Fresh foods', 'Supermarket']
</script>
<style scoped>
.custom-style .u-segmented {
--u-segmented-item-selected-color: var(--u-text-color-primary);
--u-segmented-item-selected-bg-color: #ffd100;
--u-border-radius-base: 16px;
}
</style>
隐藏源代码
分段控制器 API
分段控制器 属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| model-value / v-model | 绑定值 | string / number / boolean | — |
| options | 选项数据 | array | [] |
| props | 字段映射配置,见下表 | object | — |
| size | 尺寸 | enum | '' |
| block | 是否宽度撑满父级 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| validate-event | 是否触发表单校验 | boolean | true |
| name | 原生 name | string | — |
| id | 原生 id | string | — |
| aria-label a11y | 原生 aria-label | string | — |
| direction | 排列方向 | enum | horizontal |
props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| value | 选项对象中作为取值的字段名 | string | value |
| label | 选项对象中作为展示文案的字段名 | string | label |
| disabled | 选项对象中表示禁用态的字段名 | string | disabled |
分段控制器 事件
| 事件名 | 说明 | 类型 |
|---|---|---|
| change | 选中值变化时触发,参数为当前值 | Function |
分段控制器 插槽
| 名称 | 说明 | 类型 |
|---|---|---|
| default | 自定义选项渲染 | object |
类型声明
展开类型声明
ts
type Option = Record<string, any> | string | number | boolean