介绍
在一组可选项中进行单一选择。
代码演示
基础使用
使用 v-model 绑定当前选中值。
vue
<template>
<s-radio-group v-model="value" @change="onChange">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
const onChange = (value: any) => {
console.log('change', value)
}
</script>vue
<template>
<s-radio-group v-model="value" @change="onChange">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
const onChange = (value) => {
console.log('change', value)
}
</script>排列方向
将 direction 属性设置为 horizontal 后,单选按钮组会变成水平排列。
vue
<template>
<s-radio-group v-model="value" direction="horizontal">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
</script>vue
<template>
<s-radio-group v-model="value" direction="horizontal">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
</script>只读和禁用
只读或禁用后不可点击。
vue
<template>
<doc-title>只读</doc-title>
<s-radio-group model-value="option1" readonly>
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
<doc-title>禁用</doc-title>
<s-radio-group model-value="option1" disabled>
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>图标大小
使用 size 属性设置图标大小。
vue
<template>
<s-radio-group v-model="value" size="24px">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
</script>vue
<template>
<s-radio-group v-model="value" size="24px">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
</script>图标颜色
使用 checked-color 属性设置选中时的图标颜色。
vue
<template>
<s-radio-group v-model="value" checked-color="var(--s-color-danger)">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
</script>vue
<template>
<s-radio-group v-model="value" checked-color="var(--s-color-danger)">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
</script>图标类型
设置 type 属性为 record 可以使图标变为圆点类型。
vue
<template>
<s-radio-group v-model="value" type="record">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
</script>vue
<template>
<s-radio-group v-model="value" type="record">
<s-radio value="option1">选项1</s-radio>
<s-radio value="option2">选项2</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
</script>自定义图标
如果内置的图标不满足需求,可以使用 icon 插槽设置为任意的图标。 插槽接收checked属性表示当前的选中状态。
vue
<template>
<s-radio-group v-model="value">
<s-radio v-for="item in list" :value="item.value" :key="item.value">
<template #icon="{ checked }">
<demo-icon size="20px" :name="checked ? 'heart-fill' : 'heart'" />
</template>
{{ item.label }}
</s-radio>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option1')
const list = [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' },
]
</script>vue
<template>
<s-radio-group v-model="value">
<s-radio v-for="item in list" :value="item.value" :key="item.value">
<template #icon="{ checked }">
<demo-icon size="20px" :name="checked ? 'heart-fill' : 'heart'" />
</template>
{{ item.label }}
</s-radio>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option1')
const list = [
{
label: '选项1',
value: 'option1',
},
{
label: '选项2',
value: 'option2',
},
]
</script>自动渲染单选按钮
使用 options 属性设置可选项。
vue
<template>
<s-radio-group v-model="value" :options="options"></s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option2')
const options = Array(3)
.fill(0)
.map((_, i) => {
return {
value: `option${i + 1}`,
label: `选项${i + 1}`,
}
})
</script>vue
<template>
<s-radio-group v-model="value" :options="options"></s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option2')
const options = Array(3)
.fill(0)
.map((_, i) => {
return {
value: `option${i + 1}`,
label: `选项${i + 1}`,
}
})
</script>自定义 UI
如果只想使用单选的逻辑,并想自定义 UI,可以使用单选按钮组的 custom 插槽。
这个插槽接收 toggle方法和 value 属性作为参数。toggle 用于选中指定的选项,value 用于判断选中状态。
vue
<template>
<s-radio-group v-model="value" #default="{ toggle, value }">
<s-flex gap="medium">
<s-tag
v-for="option in options"
:key="option.value"
:color="value.includes(option.value) ? 'primary' : 'default'"
:variant="value.includes(option.value) ? 'solid' : 'filled'"
@click="toggle(option.value)"
>
{{ option.label }}
</s-tag>
</s-flex>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option2')
const options = [
{ value: 'option1', label: '选项1' },
{ value: 'option2', label: '选项2' },
{ value: 'option3', label: '选项3' },
]
</script>vue
<template>
<s-radio-group v-model="value" #default="{ toggle, value }">
<s-flex gap="medium">
<s-tag
v-for="option in options"
:key="option.value"
:color="value.includes(option.value) ? 'primary' : 'default'"
:variant="value.includes(option.value) ? 'solid' : 'filled'"
@click="toggle(option.value)"
>
{{ option.label }}
</s-tag>
</s-flex>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option2')
const options = [
{
value: 'option1',
label: '选项1',
},
{
value: 'option2',
label: '选项2',
},
{
value: 'option3',
label: '选项3',
},
]
</script>结合 list 组件使用:
vue
<template>
<s-radio-group v-model="value" #default="{ toggle, value }">
<s-list card>
<s-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
hover
@click="toggle(option.value)"
>
<template #value>
<Success v-if="option.value === value" class="text-base text-(--s-color-danger)" />
</template>
</s-list-item>
</s-list>
</s-radio-group>
</template>
<script setup lang="ts">
import { Success } from '@sard/icons'
import { ref } from 'vue'
const value = ref('option2')
const options = [
{ value: 'option1', label: '选项1' },
{ value: 'option2', label: '选项2' },
{ value: 'option3', label: '选项3' },
]
</script>vue
<template>
<s-radio-group v-model="value" #default="{ toggle, value }">
<s-list card>
<s-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
hover
@click="toggle(option.value)"
>
<template #value>
<Success v-if="option.value === value" class="text-base text-(--s-color-danger)" />
</template>
</s-list-item>
</s-list>
</s-radio-group>
</template>
<script setup lang="js">
import { Success } from '@sard/icons'
import { ref } from 'vue'
const value = ref('option2')
const options = [
{
value: 'option1',
label: '选项1',
},
{
value: 'option2',
label: '选项2',
},
{
value: 'option3',
label: '选项3',
},
]
</script>单选按钮组里面 radio 组件,会自动判断选中状态;可以给 radio 组件添加 readonly 属性以便将点击操作交给其他组件。
vue
<template>
<s-radio-group v-model="value" #default="{ toggle }">
<s-list card>
<s-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
hover
@click="toggle(option.value)"
#icon
>
<s-radio readonly :value="option.value" />
</s-list-item>
</s-list>
</s-radio-group>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref('option2')
const options = [
{ value: 'option1', label: '选项1' },
{ value: 'option2', label: '选项2' },
{ value: 'option3', label: '选项3' },
]
</script>vue
<template>
<s-radio-group v-model="value" #default="{ toggle }">
<s-list card>
<s-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
hover
@click="toggle(option.value)"
#icon
>
<s-radio readonly :value="option.value" />
</s-list-item>
</s-list>
</s-radio-group>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref('option2')
const options = [
{
value: 'option1',
label: '选项1',
},
{
value: 'option2',
label: '选项2',
},
{
value: 'option3',
label: '选项3',
},
]
</script>API
RadioProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| checked | 是否选中 | boolean | false |
| value | 单选按钮的值,配合单选按钮组一起使用 | any | - |
| label | 单选按钮标签 | string | - |
| disabled | 禁用状态 | boolean | - |
| readonly | 只读状态 | boolean | - |
| size | 图标的尺寸 | string | - |
| type | 图标类型 | 'circle' | 'record' | 'circle' |
| checked-color | 选中时图标的颜色 | string | - |
RadioSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
| icon | 自定义图标 | { checked: boolean } |
RadioEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| click | 点击时触发 | (event: MouseEvent) => void |
RadioGroupProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| model-value | 指定选中的选项 | any | - |
| disabled | 禁用状态 | boolean | - |
| readonly | 只读状态 | boolean | - |
| size | 图标的尺寸 | string | - |
| type | 图标类型 | 'circle' | 'record' | 'circle' |
| checked-color | 选中时图标的颜色 | string | - |
| direction | 排列方向 | 'horizontal' | 'vertical' | 'vertical' |
| validate-event | 是否触发表单验证 | boolean | true |
| options | 自动设置单选按钮 | RadioGroupOption[] | - |
| option-keys | 自定义 options 的 label、value 的字段 | OptionKeys | {label: 'label', value: 'value'} |
RadioGroupOption
ts
export type RadioGroupOption =
| {
[key: PropertyKey]: any
}
| string
| number
| booleanOptionKeys
ts
export interface OptionKeys {
label?: string
value?: string
}RadioGroupSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 除了使用默认组件的默认行为,也可以使用自定义组件的自定义行为 | { toggle: (value: any) => void, value: any } |
RadioGroupEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| update:modelValue | 单选按钮组值改变时触发 | (value: any) => void |
| change | 单选按钮组值改变时触发 | (value: any) => void |
主题定制
样式变量
| CSS 变量 | 值 |
|---|---|
--s-radio-group-column-gap | var(--s-size-sm) |
--s-radio-group-row-gap | var(--s-size-xs) |
--s-radio-icon-font-size | 20px |
--s-radio-icon-color | var(--s-text-color-fourth) |
--s-radio-icon-color-checked | var(--s-color-primary) |
--s-radio-icon-color-disabled | var(--s-text-color-disabled) |
--s-radio-label-margin-start | var(--s-size-xs) |