尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

radix-vue Rating 评分组件完全指南:分数值、悬停预览与 Radio Group 无障碍实现

radix-vue Rating 评分组件完全指南:分数值、悬停预览与 Radio Group 无障碍实现 radix-vue Rating 评分组件完全指南分数值、悬停预览与 Radio Group 无障碍实现【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue导读本文以 radix-vue现以reka-ui包名发布仓库中的 Rating 组件文档为核心系统讲解星级评分输入组件的完整用法从组件解剖结构Anatomy、API 参数表到分数值半星/四分之一星的 CSS 变量实现原理、可清除、悬停预览、自定义长度与只读禁用等实战场景并深入对应源码与测试用例帮助你掌握一个开箱即用、键盘可操作、支持表单提交的评分组件的全部技术细节。读完本文你将能够独立在 Vue 3 项目中实现从整星到任意分数粒度、兼顾 RTL 与无障碍的评分交互。Rating 是什么Rating 是一个星级评分输入组件用户通过它选择一个分数值并支持小数分数取值。它由RatingRoot、RatingItem、RatingItemIndicator三个部件组成底层构建在 Radio Group 之上因此天然继承了一整套单选组的无障碍能力表单提交、焦点管理、方向键导航全部开箱即用。其核心特性见 rating.md 文档包括支持受控与非受控两种模式modelValue/defaultValue通过step属性支持分数评级半星、四分之一星等悬停时预览指针下的值点击当前激活值可清除评分基于 Radio Group 构建具备完整的键盘导航与表单支持支持 RTL从右到左方向暴露 CSS 变量用于渲染部分步骤partial steps。安装从命令行安装组件该组件以reka-ui包名发布即 radix-vue 项目的当前发布名npm install reka-ui安装完成后即可在组件中按需导入 Rating 的三个部件。组件解剖Anatomy评分组件由三个部件拼装而成RatingRoot通过默认插槽暴露items每一项的列表每个RatingItem再根据根组件的step属性计算出自身包含的steps并暴露出来因此你需要为每一个 step 渲染一个 indicator。最小结构如下script setup import { RatingItem, RatingItemIndicator, RatingRoot } from reka-ui /script template RatingRoot v-slot{ items } RatingItem v-foritem in items :keyitem v-slot{ steps } :itemitem RatingItemIndicator v-forstep in steps :keystep :stepstep / /RatingItem /RatingRoot /template各部件职责一览RatingRoot包含评分全部状态当前值、悬停值、items 列表内部渲染一个 Radio GroupRatingItem包裹单个评分值如一颗星根据根部的step计算组成该 item 的steps默认渲染为labelRatingItemIndicator为 item 的每个 step 渲染交互指示器根据当前或悬停值反映该 step 是否激活。API 参考RootRatingRoot包含评分的所有部件并提供评分状态底层渲染为 Radio Group因此支持表单提交与键盘导航。完整参数见 RatingRoot 元数据名称说明类型默认值as渲染为的元素或组件可被asChild覆盖AsTag \| ComponentdivasChild将默认渲染元素改为传入的子元素并合并其 props 与行为boolean-clearable为true时点击当前选中值将评分重置为0boolean-defaultValue初始渲染时的评分值非受控模式下使用number-dir阅读方向省略时继承ConfigProvider或默认为 LTRltr \| rtl-disabled为true时阻止用户与 radio 项交互boolean-hoverable为true时悬停时预览指针下的值boolean-length渲染的评分项数量number5loop为true时键盘导航在首尾之间循环boolean-modelValue受控评分值可用v-model绑定number-name表单字段名随表单以 name/value 形式提交string-orientation组件方向vertical \| horizontalhorizontalrequired为true时表示提交表单前必须设置值boolean-step每个评分项被划分的粒度1 \| 0.5 \| 0.25 \| 0.11事件update:modelValue载荷为[payload: number]在值变化时触发。插槽默认插槽暴露modelValuenumber \| undefined与itemsnumber[]。Root 还暴露以下数据属性属性值[data-disabled]禁用时出现[data-orientation]vertical/horizontalItemRatingItem包裹单个评分值如一颗星。它根据根部的step属性计算组成该 item 的steps列表并通过默认插槽暴露默认渲染为label。完整参数见 RatingItem 元数据名称说明类型必填as渲染为的元素或组件AsTag \| Component否默认labelasChild改为渲染传入的子元素boolean否item该 item 在评分中的 1-based 索引如第 3 颗星number是插槽默认插槽暴露stepsnumber[]。ItemIndicatorRatingItemIndicator为 item 的每个 step 渲染交互指示器根据当前或悬停值反映该 step 是否激活。完整参数见 RatingItemIndicator 元数据名称说明类型必填as渲染为的元素或组件AsTag \| Component否默认divasChild改为渲染传入的子元素boolean否step该指示器表示的 step 值number是指示器暴露的数据属性属性值[data-state]active激活时[data-disabled]禁用时出现渲染部分步骤的 CSS 变量当step小于1时需要用 CSS 变量裁剪并堆叠各个 step 的宽度。RatingItemIndicator暴露以下三个 CSS 变量表格来源rating.md 文档CSS 变量说明--reka-rating-item-step-width该 step 在 item 内应占据的宽度如半星为50%--reka-rating-item-step-opacitystep 可见时为1否则为0用于堆叠重叠的 step--reka-rating-item-step-z-indexstep 的堆叠顺序使较小的 step 渲染在较大的之上一个典型的分数指示器会裁剪自身宽度并用这些变量堆叠步骤RatingItemIndicator :stepstep classabsolute overflow-hidden w-[var(--reka-rating-item-step-width)] opacity-[var(--reka-rating-item-step-opacity)] z-[var(--reka-rating-item-step-z-index)] /实战示例1. 分数评级Fractional rating通过step属性允许小于1的值。每个RatingItem会被拆分为多个steps每个 step 渲染自己的指示器并用暴露的 CSS 变量裁剪宽度。例如设置step0.5即可获得半星评分script setup import { RatingItem, RatingItemIndicator, RatingRoot } from reka-ui import { ref } from vue const rating ref(2.5) /script template RatingRoot v-slot{ items } v-modelrating :step0.5 RatingItem v-foritem in items :keyitem v-slot{ steps } :itemitem classrelative RatingItemIndicator v-forstep in steps :keystep :stepstep classabsolute overflow-hidden w-[var(--reka-rating-item-step-width)] opacity-[var(--reka-rating-item-step-opacity)] z-[var(--reka-rating-item-step-z-index)] / /RatingItem /RatingRoot /templatestep的合法取值为1 | 0.5 | 0.25 | 0.1对应整星、半星、四分之一星与十分之一星。2. 可清除Clearable使用clearable属性让用户再次点击当前选中值即可将评分重置为0template RatingRoot v-modelrating clearable !-- ... -- /RatingRoot /template3. 悬停预览Hover preview使用hoverable属性在提交前预览指针下的值。悬停时RatingItemIndicator会对悬停值及以下的所有 step 暴露data-stateactivetemplate RatingRoot v-modelrating hoverable !-- ... -- /RatingRoot /template4. 自定义长度Custom length用length属性改变渲染的评分项数量默认值为5template RatingRoot v-modelrating :length10 !-- ... -- /RatingRoot /template5. 只读 / 禁用Read-only / disabled使用disabled属性阻止交互例如展示平均评分等只读场景template RatingRoot :default-value4 disabled !-- ... -- /RatingRoot /template源码级原理三个部件如何协作深入 packages/core/src/Rating 目录可以看清上述 API 的底层实现。状态与 items 生成RatingRoot.vueRatingRoot.vue 用useVModel管理受控/非受控值默认值参数为orientation: horizontal、length: 5、step: 1。items是一个计算属性由length生成1..length的整数数组const items computed(() { return Array.from({ length: length.value }, (_, i) i 1) })changeModelValue中实现了clearable逻辑当clearable为真且点击值等于当前值时将值重置为0changeHoveredRating则在disabled或非hoverable时直接忽略。Root 通过provideRatingRootContext向子孙注入modelValue、items、hoveredRating、disabled、step及两个变更函数。值得注意的是模板层Root 渲染RadioGroupRoot并在mouseleave时无条件调用resetHoveredRating()清空悬停预览——注释说明这是为了确保即使悬停中途切换了hoverable/disabled状态指针离开后残留的预览也能被清除。steps 的计算RatingItem.vueRatingItem.vue 根据根部step计算本 item 包含的 steps以item - 1为起点、item为终点按stepSize切分向上取整得到 step 数量并生成0.5 → 1 → 1.5 → 2 …这样的递增序列保留两位小数以避免浮点误差const steps computed(() { const groupStartValue (props.item - 1) const groupEndValue props.item const stepSize rootContext.step.value const numberOfSteps Math.ceil((groupEndValue - groupStartValue) / stepSize) return Array.from({ length: numberOfSteps }, (_, index) Number((groupStartValue (index 1) * stepSize).toFixed(2))) })Item 本身只是渲染Primitive默认label并把steps通过插槽交给上层。激活态与 CSS 变量RatingItemIndicator.vueRatingItemIndicator.vue 是表现层的核心isActive决定data-stateactive悬停值大于0时取step hoveredRating否则取step modelValue即悬停预览优先于已提交值isVisible决定--reka-rating-item-step-opacity是否为1当键盘聚焦到该元素、step为整数step % 1 0、或该 step 恰好等于当前悬停值/模型值时可见——这正是堆叠的半星只露出高亮部分的实现细节三个 CSS 变量在style绑定中直接计算--reka-rating-item-step-width为step % 1 || 1乘以 100% 的宽度如 2.5 的 step 显示 50%--reka-rating-item-step-z-index为该 step 在 steps 列表中的倒序位置保证小数部分叠在大星之上。每个指示器实际渲染为一个RadioGroupItem值为该 stepselect时调用changeModelValue(step)mouseenter时调用changeHoveredRating(step)内部再用RadioGroupIndicator承载实际图标如星形 SVG这也解释了为什么整套组件天然具备 radio 的语义与表单能力。行为验证测试用例仓库自带的测试 Rating.test.ts 验证了上述全部核心行为默认选中defaultValue: 1, length: 3时第一个 radio 的data-state为active其余为undefined键盘导航聚焦第一项后按下ArrowDown会触发update:modelValue且载荷为2第二项变为active并获得焦点再按ArrowUp回到第一项悬停预览hoverable时对第三项触发mouseEnter第一、二项均变为activemouseLeave根节点后预览重置回模型值禁用状态disabled时点击任意项均不改变状态所有 radio 都带disabled与data-disabled属性无障碍默认与禁用场景均通过axe自动化无障碍测试toHaveNoViolations。无障碍与键盘交互Rating 构建在 Radio Group 原语之上遵循 WAI-ARIA 的 Radio Group 设计模式详见文档 Accessibility 一节。建议为每个 step 的指示器通过aria-label提供无障碍标签让屏幕阅读器用户理解每个指示器代表的分值。支持的键盘交互表格来源rating.md 文档按键行为Tab将焦点移动到已选项或评分第一项Space焦点在未选项上时选中该值ArrowDown将焦点和选中移到下一项ArrowRight将焦点和选中移到下一项ArrowUp将焦点和选中移到上一项ArrowLeft将焦点和选中移到上一项配合dir/ 全局ConfigProvider可支持 RTL 方向在 RTL 下左右方向键的语义会相应反转。若启用loop键盘导航会在首尾之间循环。小结Rating 是 radix-vuereka-ui中组合式原语的典型代表三部件分工明确——RatingRoot管状态与方向RatingItem按step切分粒度RatingItemIndicator用 CSS 变量完成部分步骤的裁剪与堆叠同时底层复用 Radio Group 换来了表单提交、焦点管理与完整键盘导航。若需进一步定制可参考仓库中的 story 示例 RatingDefault.story.vue其中展示了hoverablestep0.5 图标组合的真实用法以及组件导出入口 index.ts。【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表