Lzh on GitHub
一组单选按钮,用于从列表中选择一个选项。

用法

使用 v-model 指令控制 RadioGroup 的值,或者使用 default-value prop 设置初始值,当你不需要控制其状态时。

Items

使用 items prop 作为字符串或数字数组:

<script setup lang="ts">
import type { RadioGroupItem, RadioGroupValue } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
const value = ref<RadioGroupValue>('System')
</script>

<template>
  <URadioGroup v-model="value" :items="items" />
</template>

你也可以传递一个对象数组,其中包含以下属性:

  • label?: string
  • description?: string
  • value?: string
  • disabled?: boolean
  • class?: any
  • ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }

This is the first option.

This is the second option.

This is the third option.

<script setup lang="ts">
import type { RadioGroupItem, RadioGroupValue } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>([
  {
    label: 'System',
    description: 'This is the first option.',
    value: 'system'
  },
  {
    label: 'Light',
    description: 'This is the second option.',
    value: 'light'
  },
  {
    label: 'Dark',
    description: 'This is the third option.',
    value: 'dark'
  }
])
const value = ref<RadioGroupValue>('system')
</script>

<template>
  <URadioGroup v-model="value" :items="items" />
</template>
当使用对象时,你需要在 v-model 指令或 default-value prop 中引用对象的 value 属性。

值键 (Value Key)

你可以使用 value-key prop 更改用于设置值的属性。默认为 value

This is the first option.

This is the second option.

This is the third option.

<script setup lang="ts">
import type { RadioGroupItem, RadioGroupValue } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>([
  {
    label: 'System',
    description: 'This is the first option.',
    id: 'system'
  },
  {
    label: 'Light',
    description: 'This is the second option.',
    id: 'light'
  },
  {
    label: 'Dark',
    description: 'This is the third option.',
    id: 'dark'
  }
])
const value = ref<RadioGroupValue>('light')
</script>

<template>
  <URadioGroup v-model="value" value-key="id" :items="items" />
</template>

图例 (Legend)

使用 legend prop 设置 RadioGroup 的图例。

Theme
<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup legend="Theme" default-value="System" :items="items" />
</template>

颜色 (Color)

使用 color prop 更改 RadioGroup 的颜色。

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup color="neutral" default-value="System" :items="items" />
</template>

变体 (Variant) New

使用 variant prop 更改 RadioGroup 的变体。

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>([
  {
    label: 'Pro',
    value: 'pro',
    description: 'Tailored for indie hackers, freelancers and solo founders.'
  },
  {
    label: 'Startup',
    value: 'startup',
    description: 'Best suited for small teams, startups and agencies.'
  },
  {
    label: 'Enterprise',
    value: 'enterprise',
    description: 'Ideal for larger teams and organizations.'
  }
])
</script>

<template>
  <URadioGroup color="primary" variant="table" default-value="pro" :items="items" />
</template>

尺寸 (Size)

使用 size prop 更改 RadioGroup 的尺寸。

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup size="xl" variant="list" default-value="System" :items="items" />
</template>

方向 (Orientation)

使用 orientation prop 更改 RadioGroup 的方向。默认为 vertical

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup orientation="horizontal" variant="list" default-value="System" :items="items" />
</template>

指示器 (Indicator)

使用 indicator prop 更改指示器的位置或隐藏指示器。默认为 start

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup indicator="end" variant="card" default-value="System" :items="items" />
</template>

禁用 (Disabled)

使用 disabled prop 禁用 RadioGroup。

<script setup lang="ts">
import type { RadioGroupItem } from '@nuxt/ui'

const items = ref<RadioGroupItem[]>(['System', 'Light', 'Dark'])
</script>

<template>
  <URadioGroup disabled default-value="System" :items="items" />
</template>

API

Props

Prop Default Type
as

'div'

any

The element or component this component should render as.

legend

string

valueKey

'value'

string

When items is an array of objects, select the field to use as the value.

labelKey

'label'

string

When items is an array of objects, select the field to use as the label.

descriptionKey

'description'

string

When items is an array of objects, select the field to use as the description.

items

RadioGroupItem[]

size

'md'

"md" | "xs" | "sm" | "lg" | "xl"

variant

'list'

"table" | "list" | "card"

color

'primary'

"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"

orientation

'vertical'

"horizontal" | "vertical"

The orientation the radio buttons are laid out.

indicator

'start'

"start" | "end" | "hidden"

Position of the indicator.

defaultValue

null | string | number | bigint | Record<string, any>

The value of the radio item that should be checked when initially rendered.

Use when you do not need to control the state of the radio items.

modelValue

null | string | number | bigint | Record<string, any>

The controlled value of the radio item to check. Can be binded as v-model.

disabled

boolean

When true, prevents the user from interacting with radio items.

loop

boolean

When true, keyboard navigation will loop from last item to first, and vice versa.

required

boolean

When true, indicates that the user must set the value before the owning form can be submitted.

name

string

The name of the field. Submitted with its owning form as part of a name/value pair.

ui

{ root?: ClassNameValue; fieldset?: ClassNameValue; legend?: ClassNameValue; item?: ClassNameValue; container?: ClassNameValue; ... 4 more ...; description?: ClassNameValue; }

Slots

Slot Type
legend

{}

label

{ item: { [key: string]: any; label?: string | undefined; description?: string | undefined; disabled?: boolean | undefined; value?: AcceptableValue | undefined; class?: any; ui?: Pick<...> | undefined; } & { ...; }; modelValue?: AcceptableValue | undefined; }

description

{ item: { [key: string]: any; label?: string | undefined; description?: string | undefined; disabled?: boolean | undefined; value?: AcceptableValue | undefined; class?: any; ui?: Pick<...> | undefined; } & { ...; }; modelValue?: AcceptableValue | undefined; }

Emits

Event Type
change

Event

update:modelValue

string

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    radioGroup: {
      slots: {
        root: 'relative',
        fieldset: 'flex gap-x-2',
        legend: 'mb-1 block font-medium text-default',
        item: 'flex items-start',
        container: 'flex items-center',
        base: 'rounded-full ring ring-inset ring-accented overflow-hidden focus-visible:outline-2 focus-visible:outline-offset-2',
        indicator: 'flex items-center justify-center size-full after:bg-default after:rounded-full',
        wrapper: 'w-full',
        label: 'block font-medium text-default',
        description: 'text-muted'
      },
      variants: {
        color: {
          primary: {
            base: 'focus-visible:outline-primary',
            indicator: 'bg-primary'
          },
          secondary: {
            base: 'focus-visible:outline-secondary',
            indicator: 'bg-secondary'
          },
          success: {
            base: 'focus-visible:outline-success',
            indicator: 'bg-success'
          },
          info: {
            base: 'focus-visible:outline-info',
            indicator: 'bg-info'
          },
          warning: {
            base: 'focus-visible:outline-warning',
            indicator: 'bg-warning'
          },
          error: {
            base: 'focus-visible:outline-error',
            indicator: 'bg-error'
          },
          neutral: {
            base: 'focus-visible:outline-inverted',
            indicator: 'bg-inverted'
          }
        },
        variant: {
          list: {
            item: ''
          },
          card: {
            item: 'border border-muted rounded-lg'
          },
          table: {
            item: 'border border-muted'
          }
        },
        orientation: {
          horizontal: {
            fieldset: 'flex-row'
          },
          vertical: {
            fieldset: 'flex-col'
          }
        },
        indicator: {
          start: {
            item: 'flex-row',
            wrapper: 'ms-2'
          },
          end: {
            item: 'flex-row-reverse',
            wrapper: 'me-2'
          },
          hidden: {
            base: 'sr-only',
            wrapper: 'text-center'
          }
        },
        size: {
          xs: {
            fieldset: 'gap-y-0.5',
            legend: 'text-xs',
            base: 'size-3',
            item: 'text-xs',
            container: 'h-4',
            indicator: 'after:size-1'
          },
          sm: {
            fieldset: 'gap-y-0.5',
            legend: 'text-xs',
            base: 'size-3.5',
            item: 'text-xs',
            container: 'h-4',
            indicator: 'after:size-1'
          },
          md: {
            fieldset: 'gap-y-1',
            legend: 'text-sm',
            base: 'size-4',
            item: 'text-sm',
            container: 'h-5',
            indicator: 'after:size-1.5'
          },
          lg: {
            fieldset: 'gap-y-1',
            legend: 'text-sm',
            base: 'size-4.5',
            item: 'text-sm',
            container: 'h-5',
            indicator: 'after:size-1.5'
          },
          xl: {
            fieldset: 'gap-y-1.5',
            legend: 'text-base',
            base: 'size-5',
            item: 'text-base',
            container: 'h-6',
            indicator: 'after:size-2'
          }
        },
        disabled: {
          true: {
            base: 'cursor-not-allowed opacity-75',
            label: 'cursor-not-allowed opacity-75'
          }
        },
        required: {
          true: {
            legend: "after:content-['*'] after:ms-0.5 after:text-error"
          }
        }
      },
      compoundVariants: [
        {
          size: 'xs',
          variant: [
            'card',
            'table'
          ],
          class: {
            item: 'p-2.5'
          }
        },
        {
          size: 'sm',
          variant: [
            'card',
            'table'
          ],
          class: {
            item: 'p-3'
          }
        },
        {
          size: 'md',
          variant: [
            'card',
            'table'
          ],
          class: {
            item: 'p-3.5'
          }
        },
        {
          size: 'lg',
          variant: [
            'card',
            'table'
          ],
          class: {
            item: 'p-4'
          }
        },
        {
          size: 'xl',
          variant: [
            'card',
            'table'
          ],
          class: {
            item: 'p-4.5'
          }
        },
        {
          orientation: 'horizontal',
          variant: 'table',
          class: {
            item: 'first-of-type:rounded-s-lg last-of-type:rounded-e-lg',
            fieldset: 'gap-0 -space-x-px'
          }
        },
        {
          orientation: 'vertical',
          variant: 'table',
          class: {
            item: 'first-of-type:rounded-t-lg last-of-type:rounded-b-lg',
            fieldset: 'gap-0 -space-y-px'
          }
        },
        {
          color: 'primary',
          variant: 'card',
          class: {
            item: 'has-data-[state=checked]:border-primary'
          }
        },
        {
          color: 'neutral',
          variant: 'card',
          class: {
            item: 'has-data-[state=checked]:border-inverted'
          }
        },
        {
          color: 'primary',
          variant: 'table',
          class: {
            item: 'has-data-[state=checked]:bg-primary/10 has-data-[state=checked]:border-primary/50 has-data-[state=checked]:z-[1]'
          }
        },
        {
          color: 'neutral',
          variant: 'table',
          class: {
            item: 'has-data-[state=checked]:bg-elevated has-data-[state=checked]:border-inverted/50 has-data-[state=checked]:z-[1]'
          }
        },
        {
          variant: [
            'card',
            'table'
          ],
          disabled: true,
          class: {
            item: 'cursor-not-allowed opacity-75'
          }
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'list',
        orientation: 'vertical',
        indicator: 'start'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        radioGroup: {
          slots: {
            root: 'relative',
            fieldset: 'flex gap-x-2',
            legend: 'mb-1 block font-medium text-default',
            item: 'flex items-start',
            container: 'flex items-center',
            base: 'rounded-full ring ring-inset ring-accented overflow-hidden focus-visible:outline-2 focus-visible:outline-offset-2',
            indicator: 'flex items-center justify-center size-full after:bg-default after:rounded-full',
            wrapper: 'w-full',
            label: 'block font-medium text-default',
            description: 'text-muted'
          },
          variants: {
            color: {
              primary: {
                base: 'focus-visible:outline-primary',
                indicator: 'bg-primary'
              },
              secondary: {
                base: 'focus-visible:outline-secondary',
                indicator: 'bg-secondary'
              },
              success: {
                base: 'focus-visible:outline-success',
                indicator: 'bg-success'
              },
              info: {
                base: 'focus-visible:outline-info',
                indicator: 'bg-info'
              },
              warning: {
                base: 'focus-visible:outline-warning',
                indicator: 'bg-warning'
              },
              error: {
                base: 'focus-visible:outline-error',
                indicator: 'bg-error'
              },
              neutral: {
                base: 'focus-visible:outline-inverted',
                indicator: 'bg-inverted'
              }
            },
            variant: {
              list: {
                item: ''
              },
              card: {
                item: 'border border-muted rounded-lg'
              },
              table: {
                item: 'border border-muted'
              }
            },
            orientation: {
              horizontal: {
                fieldset: 'flex-row'
              },
              vertical: {
                fieldset: 'flex-col'
              }
            },
            indicator: {
              start: {
                item: 'flex-row',
                wrapper: 'ms-2'
              },
              end: {
                item: 'flex-row-reverse',
                wrapper: 'me-2'
              },
              hidden: {
                base: 'sr-only',
                wrapper: 'text-center'
              }
            },
            size: {
              xs: {
                fieldset: 'gap-y-0.5',
                legend: 'text-xs',
                base: 'size-3',
                item: 'text-xs',
                container: 'h-4',
                indicator: 'after:size-1'
              },
              sm: {
                fieldset: 'gap-y-0.5',
                legend: 'text-xs',
                base: 'size-3.5',
                item: 'text-xs',
                container: 'h-4',
                indicator: 'after:size-1'
              },
              md: {
                fieldset: 'gap-y-1',
                legend: 'text-sm',
                base: 'size-4',
                item: 'text-sm',
                container: 'h-5',
                indicator: 'after:size-1.5'
              },
              lg: {
                fieldset: 'gap-y-1',
                legend: 'text-sm',
                base: 'size-4.5',
                item: 'text-sm',
                container: 'h-5',
                indicator: 'after:size-1.5'
              },
              xl: {
                fieldset: 'gap-y-1.5',
                legend: 'text-base',
                base: 'size-5',
                item: 'text-base',
                container: 'h-6',
                indicator: 'after:size-2'
              }
            },
            disabled: {
              true: {
                base: 'cursor-not-allowed opacity-75',
                label: 'cursor-not-allowed opacity-75'
              }
            },
            required: {
              true: {
                legend: "after:content-['*'] after:ms-0.5 after:text-error"
              }
            }
          },
          compoundVariants: [
            {
              size: 'xs',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-2.5'
              }
            },
            {
              size: 'sm',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-3'
              }
            },
            {
              size: 'md',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-3.5'
              }
            },
            {
              size: 'lg',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-4'
              }
            },
            {
              size: 'xl',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-4.5'
              }
            },
            {
              orientation: 'horizontal',
              variant: 'table',
              class: {
                item: 'first-of-type:rounded-s-lg last-of-type:rounded-e-lg',
                fieldset: 'gap-0 -space-x-px'
              }
            },
            {
              orientation: 'vertical',
              variant: 'table',
              class: {
                item: 'first-of-type:rounded-t-lg last-of-type:rounded-b-lg',
                fieldset: 'gap-0 -space-y-px'
              }
            },
            {
              color: 'primary',
              variant: 'card',
              class: {
                item: 'has-data-[state=checked]:border-primary'
              }
            },
            {
              color: 'neutral',
              variant: 'card',
              class: {
                item: 'has-data-[state=checked]:border-inverted'
              }
            },
            {
              color: 'primary',
              variant: 'table',
              class: {
                item: 'has-data-[state=checked]:bg-primary/10 has-data-[state=checked]:border-primary/50 has-data-[state=checked]:z-[1]'
              }
            },
            {
              color: 'neutral',
              variant: 'table',
              class: {
                item: 'has-data-[state=checked]:bg-elevated has-data-[state=checked]:border-inverted/50 has-data-[state=checked]:z-[1]'
              }
            },
            {
              variant: [
                'card',
                'table'
              ],
              disabled: true,
              class: {
                item: 'cursor-not-allowed opacity-75'
              }
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'list',
            orientation: 'vertical',
            indicator: 'start'
          }
        }
      }
    })
  ]
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      ui: {
        radioGroup: {
          slots: {
            root: 'relative',
            fieldset: 'flex gap-x-2',
            legend: 'mb-1 block font-medium text-default',
            item: 'flex items-start',
            container: 'flex items-center',
            base: 'rounded-full ring ring-inset ring-accented overflow-hidden focus-visible:outline-2 focus-visible:outline-offset-2',
            indicator: 'flex items-center justify-center size-full after:bg-default after:rounded-full',
            wrapper: 'w-full',
            label: 'block font-medium text-default',
            description: 'text-muted'
          },
          variants: {
            color: {
              primary: {
                base: 'focus-visible:outline-primary',
                indicator: 'bg-primary'
              },
              secondary: {
                base: 'focus-visible:outline-secondary',
                indicator: 'bg-secondary'
              },
              success: {
                base: 'focus-visible:outline-success',
                indicator: 'bg-success'
              },
              info: {
                base: 'focus-visible:outline-info',
                indicator: 'bg-info'
              },
              warning: {
                base: 'focus-visible:outline-warning',
                indicator: 'bg-warning'
              },
              error: {
                base: 'focus-visible:outline-error',
                indicator: 'bg-error'
              },
              neutral: {
                base: 'focus-visible:outline-inverted',
                indicator: 'bg-inverted'
              }
            },
            variant: {
              list: {
                item: ''
              },
              card: {
                item: 'border border-muted rounded-lg'
              },
              table: {
                item: 'border border-muted'
              }
            },
            orientation: {
              horizontal: {
                fieldset: 'flex-row'
              },
              vertical: {
                fieldset: 'flex-col'
              }
            },
            indicator: {
              start: {
                item: 'flex-row',
                wrapper: 'ms-2'
              },
              end: {
                item: 'flex-row-reverse',
                wrapper: 'me-2'
              },
              hidden: {
                base: 'sr-only',
                wrapper: 'text-center'
              }
            },
            size: {
              xs: {
                fieldset: 'gap-y-0.5',
                legend: 'text-xs',
                base: 'size-3',
                item: 'text-xs',
                container: 'h-4',
                indicator: 'after:size-1'
              },
              sm: {
                fieldset: 'gap-y-0.5',
                legend: 'text-xs',
                base: 'size-3.5',
                item: 'text-xs',
                container: 'h-4',
                indicator: 'after:size-1'
              },
              md: {
                fieldset: 'gap-y-1',
                legend: 'text-sm',
                base: 'size-4',
                item: 'text-sm',
                container: 'h-5',
                indicator: 'after:size-1.5'
              },
              lg: {
                fieldset: 'gap-y-1',
                legend: 'text-sm',
                base: 'size-4.5',
                item: 'text-sm',
                container: 'h-5',
                indicator: 'after:size-1.5'
              },
              xl: {
                fieldset: 'gap-y-1.5',
                legend: 'text-base',
                base: 'size-5',
                item: 'text-base',
                container: 'h-6',
                indicator: 'after:size-2'
              }
            },
            disabled: {
              true: {
                base: 'cursor-not-allowed opacity-75',
                label: 'cursor-not-allowed opacity-75'
              }
            },
            required: {
              true: {
                legend: "after:content-['*'] after:ms-0.5 after:text-error"
              }
            }
          },
          compoundVariants: [
            {
              size: 'xs',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-2.5'
              }
            },
            {
              size: 'sm',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-3'
              }
            },
            {
              size: 'md',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-3.5'
              }
            },
            {
              size: 'lg',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-4'
              }
            },
            {
              size: 'xl',
              variant: [
                'card',
                'table'
              ],
              class: {
                item: 'p-4.5'
              }
            },
            {
              orientation: 'horizontal',
              variant: 'table',
              class: {
                item: 'first-of-type:rounded-s-lg last-of-type:rounded-e-lg',
                fieldset: 'gap-0 -space-x-px'
              }
            },
            {
              orientation: 'vertical',
              variant: 'table',
              class: {
                item: 'first-of-type:rounded-t-lg last-of-type:rounded-b-lg',
                fieldset: 'gap-0 -space-y-px'
              }
            },
            {
              color: 'primary',
              variant: 'card',
              class: {
                item: 'has-data-[state=checked]:border-primary'
              }
            },
            {
              color: 'neutral',
              variant: 'card',
              class: {
                item: 'has-data-[state=checked]:border-inverted'
              }
            },
            {
              color: 'primary',
              variant: 'table',
              class: {
                item: 'has-data-[state=checked]:bg-primary/10 has-data-[state=checked]:border-primary/50 has-data-[state=checked]:z-[1]'
              }
            },
            {
              color: 'neutral',
              variant: 'table',
              class: {
                item: 'has-data-[state=checked]:bg-elevated has-data-[state=checked]:border-inverted/50 has-data-[state=checked]:z-[1]'
              }
            },
            {
              variant: [
                'card',
                'table'
              ],
              disabled: true,
              class: {
                item: 'cursor-not-allowed opacity-75'
              }
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'list',
            orientation: 'vertical',
            indicator: 'start'
          }
        }
      }
    })
  ]
})
为了可读性,compoundVariants 中的某些颜色被省略。请查看 GitHub 上的源代码。