rate —— 评分
本頁內容尚未翻譯。
评分把「打分」变成了离散的星级选择:用户点亮星星而不是输入数字。core/rate 管的是逐星填充档位(全星/半星/空)、半星步进与浮点累积、以及 APG slider 语义——评分控件在无障碍层面是滑块,不是单选组。
- 各端实现
LhRate:商品/服务评价、难度标注、满意度调查。 - 值域为 1~N 的整数(或允许半星的 0.5 步进)的场景。
- 不该用它:需要精确小数或任意范围的连续值(用
slider或input-number);只读展示且无交互需求时仍可用 rate,但应切到readonly态。
import { LH_RATE_MAX_DEFAULT, clampRate, stepRate, getStarFill, getRateAriaText, getRateClassNames, getRateAria,} from '@lh-ui/share/core/rate'import type { LhRateState } from '@lh-ui/share/core/rate'stepRate 在加减后做 Math.round(next * 10) / 10——这不是多余,是浮点累积的防御:0.5 步进在 JS 里是 0.5 → 1.0 → 1.5 没问题,但 0.1 + 0.2 !== 0.3 这类陷阱在其它步进值下会出现,统一保留一位小数把结果钉回干净的小数。getStarFill 的判定顺序是 full → half → empty:先判整星,再判半星,保证 value=2.5 时第 3 颗是 half 而非 empty。
getRateAriaText 用 formatMessage 插值 {n},文案模板来自语言包(rate.ariaText),数值先做同样的 round 再转字符串——aria 文案与视觉填充必须基于同一个规范化后的值。
| 函数 | 签名 | 返回 | 作用 |
|---|---|---|---|
clampRate |
(value: number | undefined, max: number) => number |
钳制值 | 非数值归 0,上限由 max |
stepRate |
(value, direction: 1 | -1, allowHalf, max) => number |
步进值 | 半星 0.5 步进,一位小数 |
getStarFill |
(value, index, allowHalf) => 'full' | 'half' | 'empty' |
填充档位 | 第 index 颗星(1 起) |
getRateAriaText |
(value, template: string) => string |
aria 文案 | 插值 {n} 星 |
getRateClassNames |
(state: LhRateState & { readonly, disabled }) => string[] |
类名 | 只读/禁用修饰 |
getRateAria |
(options: { value, max, disabled?, ariaValueText? }) => LhAriaAttrs |
aria 属性包 | slider 语义 |
export interface LhRateState { max: number value: number allowHalf: boolean}
export const LH_RATE_MAX_DEFAULT = 5getRateAria 输出 slider 语义(不是 radiogroup):评分的值是连续可调的(尤其半星模式),APG 的 rating 模式常以 slider 实现。键盘交互按 slider 规约:←/→ 减/增一步。
getRateAria({ value: 4.5, max: 5 })// { role: 'slider', 'aria-valuenow': 4.5, 'aria-valuemin': 0, 'aria-valuemax': 5 }
getRateAria({ value: 0, max: 5, disabled: true, ariaValueText: '0 星' })// { role: 'slider', 'aria-valuenow': 0, 'aria-valuemin': 0, 'aria-valuemax': 5,// 'aria-disabled': true, 'aria-valuetext': '0 星' }aria-valuetext 优先于 valuenow 播报——读屏软件会念「4 星半」而不是「4.5」。每颗星按钮另需 aria-label(UI 层用 getRateAriaText(value, t('rate.ariaText')) 生成)。
import { getStarFill, stepRate, clampRate } from '@lh-ui/share/core/rate'
getStarFill(3.5, 3, true) // 'full'getStarFill(3.5, 4, true) // 'half'getStarFill(3.5, 4, false) // 'empty'(整星模式下 3.5 的第 4 颗是空)getStarFill(3.5, 5, true) // 'empty'stepRate(3, 1, true, 5) // 3.5stepRate(3.5, 1, true, 5) // 4stepRate(0, -1, true, 5) // 0(钳制)clampRate(undefined, 5) // 0clampRate(9, 5) // 5<!-- Vue3 --><div :class="getRateClassNames({ max, value, allowHalf, readonly, disabled })"> <div class="lh-rate__star-list" v-bind="getRateAria({ value, max, disabled, ariaValueText: getRateAriaText(value, t('rate.ariaText')) })" tabindex="0" @keydown.left="onStep(-1)" @keydown.right="onStep(1)" > <button v-for="i in max" :key="i" type="button" class="lh-rate__star" :class="`lh-rate__star--${getStarFill(value, i, allowHalf)}`" @click="onSelect(i)" > <LhIcon :name="getStarFill(value, i, allowHalf) === 'empty' ? 'star' : 'star-fill'" /> </button> </div></div>// React:半星模式用 hover 态决定 value,移动端用点击整星// 步进:const next = stepRate(value, dir, allowHalf, max); onChange(clampRate(next, max))// uniapp:<view> 遍历 max 颗星;非 h5 端 aria 支持有限,getRateAria 的 undefined 属性会被忽略| 类名 | 语义 |
|---|---|
.lh-rate |
基础类 |
.lh-rate--readonly |
只读(隐藏 hover 高亮、禁用指针) |
.lh-rate--disabled |
禁用 |
.lh-rate__star-list |
星组容器(tabindex 与键盘事件挂这里) |
.lh-rate__star |
单颗星按钮 |
.lh-rate__star--full / --half / --empty |
填充档位(半星用半遮挡叠加) |
.lh-rate__text |
分数文案(如「3.5 分」) |
星色 --lh-warning-color(黄),空星 --lh-fill-color / --lh-border-color。
getStarFill的 index 从 1 起,遍历用v-for="i in max"(含 max)而非v-for="i in max - 1"。- 半星与整星的一致性:
allowHalf改变后,stepRate与getStarFill必须传同一个值,否则点击与键盘步进的档位对不上。 - 只读态的语义:
readonly只切类名(视觉禁用交互),getRateAria不输出aria-disabled——只读评分仍应被读屏软件识别为可理解的评分值(靠aria-valuetext),这与 disabled 有区别。 max的边界:LH_RATE_MAX_DEFAULT是 5;UI 层允许改 max,但星过多(如 20)在窄屏会溢出,需自行换行。- value 为小数但 allowHalf 为 false:core 不校验这个组合,
getStarFill会把 3.5 当作「3 颗 full + 第 4 颗 empty」——属于调用方的配置错误,视觉上表现为截断。
@lh-ui/share/core/rate → getStarFill( )(填好参数后点运行)Copyright © 2024-2026 风默文学 | 宁ICP备2024006574号 |
苏公网安备32040002010537