uni-app中星星数对不上是因为官方uni-rate不支持滑动,需自定义touch事件将X偏移量映射为分数;实操须设max=10、step=0.5,再换算为带一位小数的星级(如4.3),并用两层图标+translateX或width百分比实现多端一致的半星裁切。

uni-app里用做星级滑动评分,为什么星星数对不上?
因为max不能设5、step不能设1——否则只能选1/2/3/4/5整数,没法支持4.3星这种设计需求。
实操建议:
-
max设为10、step设为0.5,这样滑动粒度够细,再用Math.round(value / 2 * 10) / 10转成带一位小数的星级(如4.3) - 显示层用
v-for渲染5颗星,每颗星的显隐逻辑基于index < Math.floor(rating)和rating % 1 >= 0.5判断是否半星 - H5端要加
@mouseenter/@mouseleave手动控制hover缩放,:hover伪类在H5跨端中不可靠 - 微信小程序里
touchend可能触发两次,滑动结束时要用setTimeout+clearTimeout防抖,否则rating会跳变
怎么让滑动评分组件真正支持半星+滑动+多端一致?
核心不是画星星,而是把手指X偏移量精准换算成分数。官方uni-rate不支持滑动,u-rate虽支持半星但滑动体验差(尤其iOS),真要稳定就得自己接管touchstart/touchmove/touchend。
关键点:
- 单颗星宽度必须固定(比如
36px),滑动时用event.touches[0].clientX - startX算偏移,再除以星宽、乘以max,最后Math.min/Math.max截断 - 半星裁切别用
clip-path(App端nvue不支持),改用两层图标叠放:overflow: hidden+transform: translateX(-50%)控制实心图露出比例 - 微信小程序中
touchable默认false,且文档没强调——必须显式写:touchable="true",否则点击无反馈 - App端(nvue)不支持
transform动画,得降级为两层图标+width百分比控制显隐,避免白屏或错位
自定义评分组件的props怎么设计才不翻车?
只传value和max是不够的。业务里常遇到“这个接口要×2上传”“运营临时换爱心图标”“最多打3星”,这些都该由props驱动,而不是改组件源码。
最小必要props清单:
-
value:必须是Number类型,"4.3"字符串会被当0处理 -
max:最大星数,影响UI渲染和滑动范围上限 -
step:决定最小可选分(如0.5),必须参与计算逻辑,不能只用于UI展示——否则会出现“视觉半星但value还是整数”的错觉 -
disabled:布尔值,:disabled="true"有效,disabled="true"(字符串)会失效 -
activeColor/inactiveColor:颜色必须用props传,写死在style里会导致H5暗色模式下颜色崩掉 -
icon:统一收口为图标名(如"star"或"heart"),内部用v-if分支判断是调uni-icons还是自定义font-class
为什么你写的滑动评分在小程序里点不动、H5上没hover?
根本原因不是代码写错了,而是跨端机制差异被忽略了。微信小程序里touchend事件冒泡规则和H5不同,H5的:hover伪类在uni-app编译后无法穿透到子元素。
避坑要点:
- 小程序中
view默认catchtouchend,如果父容器有catchtouchstart,子元素touchend可能被拦截——给滑动容器加catchtouchmove并阻止冒泡 - H5端hover效果必须手动控制:
@mouseenter="isHovering = true"+:class="{ 'hover-scale': isHovering }",别指望CSS伪类 - 所有绑定的
value必须在data里初始化为Number(如rating: 0),null或undefined会导致首次点击报[Vue warn] Invalid prop: type check failed - 表单校验别用
if (!this.rating),0分是合法值,应该用this.rating === undefined判断是否未选
实际项目里最常被忽略的,是step必须深度参与滑动计算逻辑——它不只是UI步长,更是数值精度的锚点。一旦漏掉这层映射,用户拖到4.3星,后台收到的却还是4,这种问题上线后很难排查。


















