uni-rate 无法满足真实业务需求,因其将 value 当整数处理、allowHalf 仅影响点击、跨端样式与事件兼容性差;需用 u-slider + 星星渲染实现稳定半星滑动,通过固定单星宽度、像素偏移映射、边界限制和防抖确保多端值严格对齐。

直接用 uni-rate 只能做基础点击评分,要支持半星、滑动、多端一致的视觉+数据精度,必须自定义——不是改样式,是重写交互逻辑。
为什么 uni-rate 不能满足真实业务需求
它内部把 value 当整数处理,allowHalf 只影响点击时是否允许选半颗,但 @change 拿到的仍是整数;H5 端 hover 要手动加事件,小程序里伪元素限制导致图标难替换;App nvue 下 clip-path 失效,半星直接不显示。常见错误包括:设了 allowHalf=true 却发现滑动还是跳星、:value 单向绑定导致点击无效、微信小程序 touchend 触发两次造成重复提交。
用 u-slider + 星星渲染实现稳定半星滑动
比手动写 touchstart/touchmove 更可靠,因为它是原生控件封装,跨端行为一致,不依赖 CSS 截断或坐标计算。
-
u-slider设:min="1"、:max="10"、:step="1",5 星制对应 1–10 分,除以 2 得 0.5 步长(如 7 → 3.5 星) - 避免用
:max="5"配:step="0.5":H5 浏览器 range 输入精度不稳定,小程序对step 支持差 - 视觉层用
v-for渲染 5 颗星,每颗根据Math.floor(sliderValue / 2)和余数(sliderValue % 2)判断显示star/star-half/star-o - 滑块本身设
opacity="0"隐藏,轨道上用absolute定位uni-icons覆盖,兼顾 nvue 兼容性
自定义 touch 事件方案的关键控制点
如果必须手写滑动(比如需要震动反馈、拖动过程实时预览),核心不在“画星星”,而在“把像素偏移映射为合法分值”。
- 单星宽度必须固定(如
30rpx),touchmove中用e.touches[0].clientX - startX算偏移,再除以该宽度得到相对位置 - 步长参与计算:半星需
Math.round(rating * 2) / 2,不能只靠 CSS 视觉截断 - 必须加边界限制:
Math.max(0, Math.min(props.max, ...)),否则滑出区域会得负数或超限值 - 微信小程序不支持动态读取
event.target.dataset.index,定位只能靠坐标,不能靠 dataset
真正难的不是实现半星,而是让“用户看到的星”和“传给后端的值”始终严格对齐——尤其在 H5 鼠标拖拽、小程序手指滑动、App nvue 手势之间,同一套逻辑要输出完全一致的浮点值。别省略防抖、别绕过边界检查、别把 step 当成纯 UI 参数。


















