ToggleGroup 切换组
按钮组形态的单选 / 多选状态切换。语义上"按下表示开",对标 Radix ToggleGroup。
English translation pending This page hasn't been translated yet — falling back to Chinese. PRs welcome on GitHub.
何时使用
- 多个按钮代表 可切换状态(粗体 / 斜体 / 下划线、对齐方式、视图模式)。
- 与
CfTabs的差别:Tabs 是导航(切换视图),ToggleGroup 是状态(设置数值)。 - 与
CfRadio的差别:Radio 是表单字段;ToggleGroup 是工具栏控件,可以单选也可以多选。
基础用法
mode="single" 默认互斥;mode="multi" 允许多选并通过 v-model 双向绑定字符串数组。
按下后会拿到 aria-pressed="true" 与 --accent-soft 染色。
背景 视口
single(单选互斥)当前:left
multi(多选)已选:draft
<script setup lang="ts">
import { ref } from 'vue';
import { CfToggleGroup, CfText } from '@chufix-design/vue';
const align = ref<string | null>('left');
const tags = ref<string[]>(['draft']);
const alignOptions = [
{ value: 'left', label: '左对齐' },
{ value: 'center', label: '居中' },
{ value: 'right', label: '右对齐' },
{ value: 'justify', label: '两端' },
];
const tagOptions = [
{ value: 'draft', label: '草稿' },
{ value: 'review', label: '待审' },
{ value: 'archive', label: '归档' },
{ value: 'star', label: '星标' },
];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 20px;">
<div>
<CfText size="sm" variant="muted">single(单选互斥)</CfText>
<CfToggleGroup
v-model="align"
:options="alignOptions"
aria-label="对齐方式"
/>
<CfText size="sm" variant="subtle">当前:{{ align ?? '未选' }}</CfText>
</div>
<div>
<CfText size="sm" variant="muted">multi(多选)</CfText>
<CfToggleGroup
v-model="tags"
:options="tagOptions"
mode="multi"
aria-label="标签"
/>
<CfText size="sm" variant="subtle">已选:{{ tags.join(' / ') || '无' }}</CfText>
</div>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfToggleGroup, CfText } from '@chufix-design/vue';
const align = ref<string | null>('left');
const tags = ref<string[]>(['draft']);
const alignOptions = [
{ value: 'left', label: '左对齐' },
{ value: 'center', label: '居中' },
{ value: 'right', label: '右对齐' },
{ value: 'justify', label: '两端' },
];
const tagOptions = [
{ value: 'draft', label: '草稿' },
{ value: 'review', label: '待审' },
{ value: 'archive', label: '归档' },
{ value: 'star', label: '星标' },
];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 20px;">
<div>
<CfText size="sm" variant="muted">single(单选互斥)</CfText>
<CfToggleGroup
v-model="align"
:options="alignOptions"
aria-label="对齐方式"
/>
<CfText size="sm" variant="subtle">当前:{{ align ?? '未选' }}</CfText>
</div>
<div>
<CfText size="sm" variant="muted">multi(多选)</CfText>
<CfToggleGroup
v-model="tags"
:options="tagOptions"
mode="multi"
aria-label="标签"
/>
<CfText size="sm" variant="subtle">已选:{{ tags.join(' / ') || '无' }}</CfText>
</div>
</div>
</template> import { useState } from 'react';
import { CfText, CfToggleGroup } from '@chufix-design/react';
export default function Demo() {
const [align, setAlign] = useState<string | null>('left');
const [tags, setTags] = useState<string[]>(['draft']);
const alignOptions = [
{ value: 'left', label: '左对齐' },
{ value: 'center', label: '居中' },
{ value: 'right', label: '右对齐' },
{ value: 'justify', label: '两端' },
];
const tagOptions = [
{ value: 'draft', label: '草稿' },
{ value: 'review', label: '待审' },
{ value: 'archive', label: '归档' },
{ value: 'star', label: '星标' },
];
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
<div>
<CfText size="sm" variant="muted">single(单选互斥)</CfText>
<CfToggleGroup value={align} onChange={setAlign} options={alignOptions} aria-label="对齐方式" />
<CfText size="sm" variant="subtle">当前:{align ?? '未选'}</CfText>
</div>
<div>
<CfText size="sm" variant="muted">multi(多选)</CfText>
<CfToggleGroup value={tags} onChange={setTags} options={tagOptions} mode="multi" aria-label="标签" />
<CfText size="sm" variant="subtle">已选:{tags.join(' / ') || '无'}</CfText>
</div>
</div>
</>
);
} import { useState } from 'react';
import { CfText, CfToggleGroup } from '@chufix-design/react';
export default function Demo() {
const [align, setAlign] = useState<string | null>('left');
const [tags, setTags] = useState<string[]>(['draft']);
const alignOptions = [
{ value: 'left', label: '左对齐' },
{ value: 'center', label: '居中' },
{ value: 'right', label: '右对齐' },
{ value: 'justify', label: '两端' },
];
const tagOptions = [
{ value: 'draft', label: '草稿' },
{ value: 'review', label: '待审' },
{ value: 'archive', label: '归档' },
{ value: 'star', label: '星标' },
];
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
<div>
<CfText size="sm" variant="muted">single(单选互斥)</CfText>
<CfToggleGroup value={align} onChange={setAlign} options={alignOptions} aria-label="对齐方式" />
<CfText size="sm" variant="subtle">当前:{align ?? '未选'}</CfText>
</div>
<div>
<CfText size="sm" variant="muted">multi(多选)</CfText>
<CfToggleGroup value={tags} onChange={setTags} options={tagOptions} mode="multi" aria-label="标签" />
<CfText size="sm" variant="subtle">已选:{tags.join(' / ') || '无'}</CfText>
</div>
</div>
</>
);
} API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
options | ToggleOption[] | — | { value, label, icon?, disabled? }[] |
modelValue / value | string | string[] | null | — | Vue v-model;React 受控 value |
mode | 'single' | 'multi' | 'single' | 单选可空 / 多选累计 |
orientation | 'horizontal' | 'vertical' | 'horizontal' | |
variant | 'attached' | 'separated' | 'attached' | 视觉上连接 / 分离 |
disabled | boolean | false | 整组禁用 |
ariaLabel | string | — | 透传 aria-label |
Events
| Vue 事件 | React 回调 | 载荷 | 说明 |
|---|---|---|---|
update:modelValue | — | 新值 | v-model 同步 |
change | onChange | ToggleGroupChangePayload | { value, changedValue };changedValue 是本次点击的 option.value |
反馈与讨论
ToggleGroup 切换组 · Discussion