Appearance
Radio 单选框
用于在一组互斥选项中选择一个结果,适合状态切换、筛选条件、配置项选择。
何时使用
- 多个选项互斥,且用户必须或通常只选择一个。
- 选项数量较少,需要直接展示全部选项。
- 需要用按钮样式表达更强的分段控制感。
基础用法
当前:a
vue
<template>
<x-radio-group v-model="value" name="basic-radio">
<x-radio value="a">选项 A</x-radio>
<x-radio value="b">选项 B</x-radio>
</x-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('a');
</script>选项配置
vue
<template>
<x-radio-group v-model="value" :options="options" name="time-radio" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('day');
const options = [
{ label: '今日', value: 'day' },
{ label: '本周', value: 'week' },
{ label: '本月', value: 'month' },
];
</script>禁用状态
vue
<template>
<x-radio-group v-model="value" :options="options" />
<x-radio-group v-model="value" :options="options" disabled />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('enabled');
const options = [
{ label: '启用', value: 'enabled' },
{ label: '禁用项', value: 'disabled', disabled: true },
{ label: '归档', value: 'archived' },
];
</script>按钮样式
vue
<template>
<x-radio-group v-model="value" type="button" :options="options" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('design');
const options = [{ label: '设计', value: 'design' }, { label: '开发', value: 'dev' }, { label: '测试', value: 'test' }];
</script>尺寸
vue
<template>
<x-radio-group v-model="value" type="button" size="mini" :options="options" />
<x-radio-group v-model="value" type="button" size="small" :options="options" />
<x-radio-group v-model="value" type="button" size="medium" :options="options" />
<x-radio-group v-model="value" type="button" size="large" :options="options" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('design');
const options = [{ label: '设计', value: 'design' }, { label: '开发', value: 'dev' }, { label: '测试', value: 'test' }];
</script>纵向排列
vue
<template>
<x-radio-group v-model="value" direction="vertical" :options="options" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('design');
const options = [{ label: '设计', value: 'design' }, { label: '开发', value: 'dev' }, { label: '测试', value: 'test' }];
</script>自定义文案
vue
<template>
<x-radio-group v-model="value" :options="options">
<template #label="{ data }">
<span>{{ data.label }}角色</span>
</template>
</x-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('design');
const options = [{ label: '设计', value: 'design' }, { label: '开发', value: 'dev' }, { label: '测试', value: 'test' }];
</script>自定义单选框图形
vue
<template>
<x-radio-group v-model="value" :options="options">
<template #radio="{ checked, disabled }">
<span :class="{ 'is-checked': checked, 'is-disabled': disabled }" />
</template>
</x-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('design');
const options = [{ label: '设计', value: 'design' }, { label: '开发', value: 'dev' }, { label: '测试', value: 'test' }];
</script>布尔值选项
vue
<template>
<x-radio-group v-model="value" :options="options" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref(true);
const options = [
{ label: '启用', value: true },
{ label: '停用', value: false },
];
</script>事件
vue
<template>
<x-radio-group v-model="value" :options="options" @change="handleChange" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('read');
const handleChange = (value: string | number | boolean) => {
console.log(value);
};
</script>在 Form 中校验
组件放进 x-form-item 后会自动继承 Form 的尺寸与禁用状态,并按 FormItem 的校验规则展示错误。默认 validateTrigger 为 change,即值变化时触发校验。
vue
<template>
<x-form ref="formRef" :model="formState" :rules="formRules">
<x-form-item field="plan" label="套餐">
<x-radio-group v-model="formState.plan">
<x-radio value="basic">基础版</x-radio>
<x-radio value="pro">专业版</x-radio>
</x-radio-group>
</x-form-item>
<x-form-item>
<x-space>
<x-button type="primary" @click="handleValidate">校验</x-button>
<x-button @click="handleReset">重置</x-button>
</x-space>
</x-form-item>
</x-form>
<p role="status">{{ validateResult }}</p>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import type { FormInstance, FieldRule } from 'x-next';
const formState = reactive({ plan: undefined as string | undefined });
const formRules: Record<string, FieldRule[]> = {
plan: [{ required: true, message: '请选择套餐' }],
};
const formRef = ref<FormInstance>();
const validateResult = ref('');
const handleValidate = async () => {
const errors = await formRef.value!.validate();
validateResult.value = errors
? `校验失败:${Object.values(errors).map((error) => error.message).join(';')}`
: '校验通过';
};
const handleReset = () => {
formRef.value!.resetFields();
validateResult.value = '已重置';
};
</script>按需导入
RadioGroup 会为同组原生 radio 自动生成稳定 name,支持浏览器的方向键切换;也可以显式设置 name。单个 Radio 的 name 优先级更高,建议同组保持一致。
ts
import { Radio, RadioGroup } from 'x-next';样式按需引入(base.css 为共享基础层,多个组件只需引入一次):
ts
import 'x-next/style/base.css';
import 'x-next/style/form-radio.css';Radio Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 绑定值 | RadioValue | undefined |
defaultChecked | 默认是否选中,非受控模式 | boolean | false |
value | 选项值 | RadioValue | true |
type | 单选类型 | 'radio' | 'button' | 'radio' |
disabled | 是否禁用 | boolean | false |
name | 原生 input 的 name 属性,优先级高于 RadioGroup 的 name | string | - |
id | 原生 input 的 id 属性 | string | - |
size | 组件尺寸 | 'mini' | 'small' | 'medium' | 'large' | 跟随全局配置 |
Radio Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 值更新时触发 | value: RadioValue |
change | 值变化时触发 | value: RadioValue, event: Event |
Radio Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
default | 单选框文案 | - |
radio | 自定义单选框图形 | { checked, disabled } |
RadioGroup Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 绑定值 | RadioValue | undefined |
defaultValue | 默认值,非受控模式 | RadioValue | '' |
type | 单选组类型 | 'radio' | 'button' | 'radio' |
size | 单选组尺寸 | 'mini' | 'small' | 'medium' | 'large' | 跟随全局配置 |
options | 选项数据 | Array<RadioValue | RadioOption> | - |
direction | 排列方向 | 'horizontal' | 'vertical' | 'horizontal' |
disabled | 是否禁用 | boolean | false |
name | 传给组内原生 input 的 name 属性,运行时修改会同步 | string | 自动生成稳定组名 |
ariaLabel | 原生 radiogroup 的 aria-label 属性 | string | - |
RadioGroup Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 值更新时触发 | value: RadioValue |
change | 值变化时触发 | value: RadioValue, event: Event |
RadioGroup Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
default | 自定义单选框列表 | - |
label | 自定义 options 文案 | { data } |
radio | 自定义单选框图形 | { checked, disabled } |
类型
ts
type RadioValue = string | number | boolean;
interface RadioOption {
label?: string | (() => VNode);
value: RadioValue;
disabled?: boolean;
}