Radio Group 单项选择
用于单项选择场景的 MoriUI 组件。
资源
导入
import { RadioGroup, RadioGroupItem } from 'moriui'组合方式
RadioGroup 管理唯一选中值,RadioGroupItem 以必填 value 标识选项;标签、说明与错误由 Field 组合。
受控与默认值
使用 v-model 持有当前 AcceptableValue;无需受控时可用 defaultValue 设置初始选择。
禁用与无效
disabled 可设置在整组或单个 Item;无效项使用 aria-invalid,外围 Field 使用 data-invalid。
RTL
dir 影响方向键顺序与内容阅读方向,Reka UI 负责 roving focus 和循环导航。
示例
概览
用 v-model 在三个界面密度中保持唯一选择。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldLabel, RadioGroup, RadioGroupItem } from 'moriui'
const density = shallowRef('comfortable')
</script>
<template>
<RadioGroup v-model="density" aria-label="界面密度" class="w-fit">
<Field v-for="item in [['default', '默认'], ['comfortable', '舒适'], ['compact', '紧凑']]" :key="item[0]" orientation="horizontal">
<RadioGroupItem :id="`density-${item[0]}`" :value="item[0]" />
<FieldLabel :for="`density-${item[0]}`">
{{ item[1] }}
</FieldLabel>
</Field>
</RadioGroup>
</template>
说明
FieldContent 为每个选项组合标签与帮助文字。
适合大多数场景的标准间距。
为内容保留更多呼吸空间。
适合信息密集的操作界面。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
RadioGroup,
RadioGroupItem
} from 'moriui'
const density = shallowRef('comfortable')
const options = [
{ value: 'default', label: '默认', description: '适合大多数场景的标准间距。' },
{ value: 'comfortable', label: '舒适', description: '为内容保留更多呼吸空间。' },
{ value: 'compact', label: '紧凑', description: '适合信息密集的操作界面。' }
]
</script>
<template>
<RadioGroup v-model="density" class="w-full max-w-xs">
<Field v-for="item in options" :key="item.value" orientation="horizontal">
<RadioGroupItem :id="`description-${item.value}`" :value="item.value" />
<FieldContent>
<FieldLabel :for="`description-${item.value}`">
{{ item.label }}
</FieldLabel>
<FieldDescription>{{ item.description }}</FieldDescription>
</FieldContent>
</Field>
</RadioGroup>
</template>
选择卡片
FieldLabel 包裹整行内容,扩大可点击区域。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
FieldTitle,
RadioGroup,
RadioGroupItem
} from 'moriui'
const plan = shallowRef('plus')
const plans = [
{ value: 'plus', title: 'Plus', description: '适合个人与小型团队。' },
{ value: 'pro', title: 'Pro', description: '适合持续增长的业务。' },
{ value: 'enterprise', title: 'Enterprise', description: '适合大型团队与企业。' }
]
</script>
<template>
<RadioGroup v-model="plan" class="w-full max-w-sm">
<FieldLabel v-for="item in plans" :key="item.value" :for="`plan-${item.value}`">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>{{ item.title }}</FieldTitle>
<FieldDescription>{{ item.description }}</FieldDescription>
</FieldContent>
<RadioGroupItem :id="`plan-${item.value}`" :value="item.value" />
</Field>
</FieldLabel>
</RadioGroup>
</template>
字段集
FieldSet 与 FieldLegend 建立订阅方案的语义分组。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldDescription,
FieldLabel,
FieldLegend,
FieldSet,
RadioGroup,
RadioGroupItem
} from 'moriui'
const plan = shallowRef('monthly')
</script>
<template>
<FieldSet class="w-full max-w-xs">
<FieldLegend variant="label">
订阅方案
</FieldLegend>
<FieldDescription>年付与终身方案可节省更多费用。</FieldDescription>
<RadioGroup v-model="plan">
<Field v-for="item in [['monthly', '月付(¥68/月)'], ['yearly', '年付(¥680/年)'], ['lifetime', '终身(¥1,980)']]" :key="item[0]" orientation="horizontal">
<RadioGroupItem :id="`subscription-${item[0]}`" :value="item[0]" />
<FieldLabel :for="`subscription-${item[0]}`">
{{ item[1] }}
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
</template>
禁用
单个 disabled 项与可选项共存。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Field, FieldLabel, RadioGroup, RadioGroupItem } from 'moriui'
const option = shallowRef('option-2')
</script>
<template>
<RadioGroup v-model="option" class="w-fit">
<Field orientation="horizontal" data-disabled>
<RadioGroupItem id="disabled-option-1" value="option-1" disabled />
<FieldLabel for="disabled-option-1">
不可选选项
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem id="disabled-option-2" value="option-2" />
<FieldLabel for="disabled-option-2">
选项二
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem id="disabled-option-3" value="option-3" />
<FieldLabel for="disabled-option-3">
选项三
</FieldLabel>
</Field>
</RadioGroup>
</template>
无效
aria-invalid 与 Field data-invalid 同步错误状态。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldDescription,
FieldLabel,
FieldLegend,
FieldSet,
RadioGroup,
RadioGroupItem
} from 'moriui'
const channel = shallowRef('email')
</script>
<template>
<FieldSet class="w-full max-w-xs">
<FieldLegend variant="label">
通知偏好
</FieldLegend>
<FieldDescription>请重新确认接收通知的方式。</FieldDescription>
<RadioGroup v-model="channel">
<Field
v-for="item in [['email', '仅邮件'], ['sms', '仅短信'], ['both', '邮件和短信']]"
:key="item[0]"
orientation="horizontal"
data-invalid
>
<RadioGroupItem :id="`invalid-${item[0]}`" :value="item[0]" aria-invalid="true" />
<FieldLabel :for="`invalid-${item[0]}`">
{{ item[1] }}
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
</template>
RTL
阿拉伯语选项使用 RTL 方向与正确的键盘顺序。
تباعد قياسي لمعظم حالات الاستخدام.
مساحة أكبر بين العناصر.
تباعد أدنى للتخطيطات الكثيفة.
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
RadioGroup,
RadioGroupItem
} from 'moriui'
const density = shallowRef('comfortable')
const options = [
{ value: 'default', label: 'افتراضي', description: 'تباعد قياسي لمعظم حالات الاستخدام.' },
{ value: 'comfortable', label: 'مريح', description: 'مساحة أكبر بين العناصر.' },
{ value: 'compact', label: 'مضغوط', description: 'تباعد أدنى للتخطيطات الكثيفة.' }
]
</script>
<template>
<RadioGroup v-model="density" class="w-full max-w-xs" dir="rtl">
<Field v-for="item in options" :key="item.value" orientation="horizontal">
<RadioGroupItem :id="`rtl-density-${item.value}`" :value="item.value" />
<FieldContent>
<FieldLabel :for="`rtl-density-${item.value}`">
{{ item.label }}
</FieldLabel>
<FieldDescription>{{ item.description }}</FieldDescription>
</FieldContent>
</Field>
</RadioGroup>
</template>
API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| RadioGroup v-model | AcceptableValue | undefined | 当前唯一选中值。 |
| RadioGroup defaultValue | AcceptableValue | undefined | 非受控初始选中值。 |
| RadioGroup disabled / required | boolean | false | 整组禁用与表单必填语义。 |
| RadioGroup orientation | 'horizontal' | 'vertical' | undefined | 方向键导航方向。 |
| RadioGroup dir / loop | 'ltr' | 'rtl' / boolean | 继承 / true | 阅读方向与循环键盘导航。 |
| RadioGroupItem value | AcceptableValue | — | 必填的选项值。 |
| RadioGroupItem disabled | boolean | false | 单独禁用当前选项。 |
无障碍说明
RadioGroup 复用 Reka UI 的 radiogroup/radio ARIA、方向键、Space 选择与 roving focus。整组应有 FieldLegend 或 aria-label,每个 Item 必须关联可读标签;错误同时使用 aria-invalid 与文字说明。
关联组件
这个组件暂时没有登记关联条目。