值:4
<script setup lang="ts">
import { ref } from 'vue'
import { Rating, Stack, Text } from '@hina-ui/vue'
const score = ref(4)
</script>
<template>
<Stack gap="sm" align="start">
<Rating v-model="score" size="lg" aria-label="评分" />
<Text tone="muted" size="sm">值:{{ score }}</Text>
</Stack>
</template>
vue
用法
import { Rating } from '@hina-ui/vue'
ts
评分由一排星组成,点击某颗星即选中该分值,悬停时前面的星预览为实心。v-model 绑定分值,max 指定满分,默认为 5。不传 stars 时星数与 max 相同;传入 stars 可独立指定显示的星数。未声明的属性都会传给包裹各星的组元素,请用 aria-label 或者 aria-labelledby 命名。
值:0
<script setup lang="ts">
import { ref } from 'vue'
import { Rating, Stack, Text } from '@hina-ui/vue'
const score = ref(0)
</script>
<template>
<Stack gap="sm" align="start">
<Rating v-model="score" aria-label="评分" />
<Text tone="muted" size="sm">值:{{ score }}</Text>
</Stack>
</template>
vue
示例
半星
step 设为 0.5 时每颗星分成左右两半,可以选出 2.5 这样的分值。
值:2.5
<script setup lang="ts">
import { ref } from 'vue'
import { Rating, Stack, Text } from '@hina-ui/vue'
const score = ref(2.5)
</script>
<template>
<Stack gap="sm" align="start">
<Rating v-model="score" :step="0.5" aria-label="评分" />
<Text tone="muted" size="sm">值:{{ score }}</Text>
</Stack>
</template>
vue
分制与星数
max 为满分,stars 为显示的星数。设置 :max="10" :stars="5" 时,每颗星代表 2 分,值 7 显示为 3.5 颗星。
step 仍以星为单位:默认 1 表示整星,此时每次选择相差 2 分;设为 0.5 后每次相差 1 分。v-model、update:modelValue 和通过 name 提交的表单值始终使用实际分值。只读展示按比例填充,不受 step 限制。
7 / 10
8.6 / 10 · 只读
<script setup lang="ts">
import { ref } from 'vue'
import { Inline, Rating, Stack, Text } from '@hina-ui/vue'
const score = ref(7)
</script>
<template>
<Stack gap="md" align="start">
<Inline gap="sm">
<Rating v-model="score" :max="10" :stars="5" :step="0.5" aria-label="评分" />
<Text tone="muted" size="sm">{{ score }} / 10</Text>
</Inline>
<Inline gap="sm">
<Rating :model-value="8.6" :max="10" :stars="5" readonly />
<Text tone="muted" size="sm">8.6 / 10 · 只读</Text>
</Inline>
</Stack>
</template>
vue
只读展示
readonly 把评分渲染为只展示的图形,值可以是任意小数,星按比例填充,适合展示平均分。
4.3 分,共 128 人评分
<script setup lang="ts">
import { Inline, Rating, Text } from '@hina-ui/vue'
</script>
<template>
<Inline gap="sm">
<Rating :model-value="4.3" readonly />
<Text tone="muted" size="sm">4.3 分,共 128 人评分</Text>
</Inline>
</template>
vue
尺寸
size 有 sm、md、lg 三档。
<script setup lang="ts">
import { Rating, Stack } from '@hina-ui/vue'
</script>
<template>
<Stack align="start">
<Rating :model-value="3" size="sm" aria-label="小号" />
<Rating :model-value="3" size="md" aria-label="中号" />
<Rating :model-value="3" size="lg" aria-label="大号" />
</Stack>
</template>
vue
状态
disabled 禁用整组;clearable 默认开启,再次点击已选中的星会清零,关闭后不会。
<script setup lang="ts">
import { ref } from 'vue'
import { Rating, Stack } from '@hina-ui/vue'
const fixed = ref(3)
</script>
<template>
<Stack align="start">
<Rating :model-value="3" disabled aria-label="已禁用" />
<Rating v-model="fixed" :clearable="false" aria-label="不可清零" />
</Stack>
</template>
vue
在表单中
放进 FormField 后,标签通过 aria-labelledby 关联到整组星,错误信息由字段渲染;校验规则与提交交给 Form。未打分时值是 0。
<script setup lang="ts">
import { reactive, ref } from 'vue'
import * as v from 'valibot'
import { Button, Form, FormField, Rating, Text } from '@hina-ui/vue'
const schema = v.object({
score: v.pipe(v.number(), v.minValue(1, '请先打分')),
})
const values = reactive({ score: 0 })
const saved = ref('')
async function save(data: unknown) {
await new Promise(resolve => setTimeout(resolve, 600))
saved.value = JSON.stringify(data)
}
</script>
<template>
<Form v-slot="{ submitting }" :values="values" :rules="schema" class="w-80" @submit="save">
<FormField name="score" label="评分" required>
<Rating v-model="values.score" />
</FormField>
<Button type="submit" :loading="submitting" class="self-start">提交评价</Button>
<Text v-if="saved" tone="muted" size="sm">已提交:{{ saved }}</Text>
</Form>
</template>
vue
行为
- 点击一颗星即选中该分值,再次点击同一颗星清零;悬停时前面的星预览为实心,移开后恢复。
- 焦点落在某颗星上时,左右方向键移动焦点并选中,与单选框组相同。
- 星的颜色变化有过渡。
无障碍
- 可交互时整组是
role="radiogroup",每颗星或者每半颗星是带本地化名称的role="radio"。 - 只读时整组是
role="img",名称是语言包给出的「n 星,满分 m 星」。星数与满分不同时,单选项与只读图形的名称使用实际分值,如「7 分,满分 10 分」。 - 通过
aria-label或者aria-labelledby为整组命名。
API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | number | 0 | 分值 |
max | number | 5 | 满分,须大于 0;未指定 stars 时也决定星数 |
stars | number | max | 显示的星数,须为正整数 |
step | 1 | 0.5 | 1 | 以星为单位的步长;实际分值步长为 max / stars * step |
clearable | boolean | true | 再次点击已选中的星是否清零 |
readonly | boolean | false | 是否只展示 |
name | string | — | 表单字段名 |
size | 'sm' | 'md' | 'lg' | 'md' | 尺寸 |
disabled | boolean | false | 是否禁用 |
class | string | — | 追加至根元素的类名 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | value: number | 分值变化 |