输入评级

评级GitHub
显示和收集用户评级的组件。

用法

使用v-model指令控制InputRating组件的评级值。

<script setup lang="ts">
const value = ref(3)
</script>

<template>
  <UInputRating v-model="value" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(3)
</script>

<template>
  <UInputRating v-model="value" />
</template>

当不需要控制其状态时,使用default-value属性设置初始值。

<template>
  <UInputRating :default-value="3" />
</template>

Step

使用step道具控制每个星星的粒度。将其设置为0.5以允许半颗星星评级。

<template>
  <UInputRating :step="0.5" :default-value="3.5" />
</template>

Length

使用length道具将stars.xml2的数量设置为5。

<template>
  <UInputRating :length="10" :step="0.5" :default-value="7.5" />
</template>

可清除

使用clearable道具允许用户通过点击当前选择的值来清除评级。

<template>
  <UInputRating clearable :default-value="3" />
</template>

可悬停

使用hoverable道具来控制当鼠标悬停在星星上时评级是否预览该值。

<template>
  <UInputRating hoverable :default-value="3" />
</template>

Icon

使用icon道具自定义用于星星的图标。

<template>
  <UInputRating icon="i-lucide-heart" :default-value="4" />
</template>
您可以自定义默认的星星图标全球在您的app.config.ts下ui.icons.star的关键。
您可以自定义默认的星星图标全球在您的vite.config.ts下ui.icons.star键。

空图标

使用empty-icon道具自定义空星星的图标。如果没有提供,则使用与icon相同的图标。

<template>
  <UInputRating empty-icon="i-lucide-circle" icon="i-lucide-circle-check" :default-value="3" />
</template>

Color

使用color道具更改填充星星的颜色。

<template>
  <UInputRating color="neutral" :default-value="4" />
</template>

Size

使用size道具来改变星星的大小。

<template>
  <UInputRating size="xl" :default-value="4" />
</template>

定向

使用orientation属性将rating. xm的方向更改为horizontal。

<template>
  <UInputRating orientation="vertical" :default-value="4" />
</template>

禁用

使用disabled属性禁用InputRating组件。禁用时,该组件的不透明度降低(75%),并显示not-allowed光标以指示它不是交互式的。

<template>
  <UInputRating disabled :default-value="3" />
</template>

只读

使用readonly属性显示评级,而不允许用户交互。与disabled不同,它保持正常外观(完全不透明,默认光标)。当您希望显示无法更改但应正常显示的评级时使用。

<template>
  <UInputRating readonly :default-value="4.5" />
</template>

API

Props

Prop Default Type
as
'div'
any

The element or component this component should render as.

id
string

The id of the rating.

readonly
false
boolean

Make the rating readonly (non-interactive).

icon
appConfig.ui.icons.star
any

The icon displayed for each rating value.

emptyIcon
any

The icon displayed for empty rating values. Defaults to icon when not provided.

color
'primary'
"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
size
'md'
"xs" | "sm" | "md" | "lg" | "xl"
orientation
'horizontal'
"horizontal" | "vertical"

The orientation of the rating.

step
1
1 | 0.5 | 0.25 | 0.1

The granularity each rating item is divided into.

disabled
boolean

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

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.

defaultValue
0
number

The rating value when initially rendered. Use when you do not need to control the state of the rating.

modelValue
number

The controlled rating value. Can be bound with v-model.

length
5
number

The number of rating items to render.

clearable
false
boolean

When true, clicking the currently selected rating resets the value to 0.

hoverable
false
boolean

When true, the rating previews the value under the pointer on hover.

ui
{ root?: SlotClass; item?: SlotClass; indicator?: SlotClass; icon?: SlotClass; emptyIcon?: SlotClass; }

Slots

Slot Type
item
{ index: number; filled: boolean; }

Rendered for each item. filled is false for the empty background layer and true for the highlighted overlay.

Emits

Event Type
update:modelValue
[payload: number]
change
[event: Event]

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    inputRating: {
      slots: {
        root: '',
        item: [
          'relative inline-block cursor-pointer select-none rounded-sm has-focus-visible:outline-3',
          'transition'
        ],
        indicator: 'absolute inset-0 overflow-hidden outline-none text-transparent w-(--reka-rating-item-step-width) opacity-(--reka-rating-item-step-opacity) z-(--reka-rating-item-step-z-index)',
        icon: 'block',
        emptyIcon: 'block w-full h-full text-muted pointer-events-none'
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'inline-flex items-center gap-0.5'
          },
          vertical: {
            root: 'inline-flex flex-col items-center gap-0.5'
          }
        },
        size: {
          xs: {
            item: 'size-3',
            icon: 'size-3'
          },
          sm: {
            item: 'size-4',
            icon: 'size-4'
          },
          md: {
            item: 'size-5',
            icon: 'size-5'
          },
          lg: {
            item: 'size-6',
            icon: 'size-6'
          },
          xl: {
            item: 'size-7',
            icon: 'size-7'
          }
        },
        color: {
          primary: {
            indicator: 'data-[state=active]:text-primary',
            item: 'outline-primary/25'
          },
          secondary: {
            indicator: 'data-[state=active]:text-secondary',
            item: 'outline-secondary/25'
          },
          success: {
            indicator: 'data-[state=active]:text-success',
            item: 'outline-success/25'
          },
          info: {
            indicator: 'data-[state=active]:text-info',
            item: 'outline-info/25'
          },
          warning: {
            indicator: 'data-[state=active]:text-warning',
            item: 'outline-warning/25'
          },
          error: {
            indicator: 'data-[state=active]:text-error',
            item: 'outline-error/25'
          },
          neutral: {
            indicator: 'data-[state=active]:text-highlighted',
            item: 'outline-inverted/25'
          }
        },
        readonly: {
          true: {
            root: 'cursor-default',
            item: 'cursor-default'
          },
          false: {}
        },
        disabled: {
          true: {
            root: 'opacity-75 cursor-not-allowed',
            item: 'cursor-not-allowed pointer-events-none'
          },
          false: {}
        }
      },
      compoundVariants: [
        {
          readonly: false,
          disabled: false,
          class: {
            item: 'hover:scale-110'
          }
        }
      ],
      defaultVariants: {
        color: 'primary',
        size: 'md'
      }
    }
  }
})
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: {
        inputRating: {
          slots: {
            root: '',
            item: [
              'relative inline-block cursor-pointer select-none rounded-sm has-focus-visible:outline-3',
              'transition'
            ],
            indicator: 'absolute inset-0 overflow-hidden outline-none text-transparent w-(--reka-rating-item-step-width) opacity-(--reka-rating-item-step-opacity) z-(--reka-rating-item-step-z-index)',
            icon: 'block',
            emptyIcon: 'block w-full h-full text-muted pointer-events-none'
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'inline-flex items-center gap-0.5'
              },
              vertical: {
                root: 'inline-flex flex-col items-center gap-0.5'
              }
            },
            size: {
              xs: {
                item: 'size-3',
                icon: 'size-3'
              },
              sm: {
                item: 'size-4',
                icon: 'size-4'
              },
              md: {
                item: 'size-5',
                icon: 'size-5'
              },
              lg: {
                item: 'size-6',
                icon: 'size-6'
              },
              xl: {
                item: 'size-7',
                icon: 'size-7'
              }
            },
            color: {
              primary: {
                indicator: 'data-[state=active]:text-primary',
                item: 'outline-primary/25'
              },
              secondary: {
                indicator: 'data-[state=active]:text-secondary',
                item: 'outline-secondary/25'
              },
              success: {
                indicator: 'data-[state=active]:text-success',
                item: 'outline-success/25'
              },
              info: {
                indicator: 'data-[state=active]:text-info',
                item: 'outline-info/25'
              },
              warning: {
                indicator: 'data-[state=active]:text-warning',
                item: 'outline-warning/25'
              },
              error: {
                indicator: 'data-[state=active]:text-error',
                item: 'outline-error/25'
              },
              neutral: {
                indicator: 'data-[state=active]:text-highlighted',
                item: 'outline-inverted/25'
              }
            },
            readonly: {
              true: {
                root: 'cursor-default',
                item: 'cursor-default'
              },
              false: {}
            },
            disabled: {
              true: {
                root: 'opacity-75 cursor-not-allowed',
                item: 'cursor-not-allowed pointer-events-none'
              },
              false: {}
            }
          },
          compoundVariants: [
            {
              readonly: false,
              disabled: false,
              class: {
                item: 'hover:scale-110'
              }
            }
          ],
          defaultVariants: {
            color: 'primary',
            size: 'md'
          }
        }
      }
    })
  ]
})

Changelog

No recent changes