直接用 uni-rate 难以自定义风格,因其依赖小程序原生机制,CSS 伪元素、hover、transform 在 H5 和小程序中表现不一致;图标固定,active/inactive-color 仅支持颜色无法改形状或加动画;u-rate 结构清晰、支持 slot 和 icon prop,更易定制;复杂需求需手写 DOM 控制半星、滑动、震动等交互;高复用组件须覆盖 value/max/step/icon/size/showText/textMap 等 props,并注意 v-model 初始化非 undefined。

为什么直接用 uni-rate 很难自定义风格
它底层依赖小程序原生组件机制,CSS 伪元素、hover、transform 动画在 H5 和小程序里表现不一致;图标只能用固定字体或图片,没法换心形/火苗等运营指定图形;更关键的是,uni-rate 的 active-color 和 inactive-color 只控制颜色,不能改形状、加阴影、做缩放反馈——这些恰恰是“自定义风格”的核心。
用 u-rate 做基础,再覆盖样式最省事
u-rate 是 uView 提供的 uni-app 兼容版评分组件,支持 allow-half、disabled、v-model,且 DOM 结构清晰(每颗星是独立 view 包裹两个图标),方便 CSS 精准控制。
- 别用
!important硬盖全局样式,而是给u-rate加个 class,比如class="my-star",然后在 scoped style 里写:.my-star .u-rate__icon { font-size: 32px; } - 想换图标?传
iconprop::icon="'heart'"(需提前在u-icons里注册),或用slot自定义内容 - H5 端加 hover 缩放:不能只靠
:hover,得监听@mouseenter/@mouseleave切换 class,否则小程序里会报错 - 颜色别写死,用 CSS 变量:
--u-rate-active-color: var(--primary-color),方便暗色模式切换
需要彻底自由?手写 view + uni-icons 组件
当设计稿要求“半颗星带渐变边框”“滑动时星星逐个点亮”“点击有震动反馈”,就得自己控 DOM。核心不是画星星,而是把用户操作映射成分数,并实时渲染。
- 结构用
v-for渲染max颗星,每颗星内部放两个uni-icons(空心+实心),通过clip-path: inset(0 0 0 50%)或overflow: hidden+transform: translateX()实现半星裁切 - 滑动逻辑:监听
touchstart→touchmove,算出手指 X 偏移 / 单星宽度 ×max,再用Math.round(val / step) * step对齐步长(如step=0.5) - App 端(nvue)不支持
clip-path,得降级为两层图标 +width: 50%控制显隐,否则半星显示异常 - 微信小程序里
touchend可能触发两次,必须用setTimeout+clearTimeout防抖,不然用户点一下,v-model更新两次
容易被忽略的细节:props 设计决定复用上限
很多团队写完一个评分组件就扔进项目里,结果下个需求要“3 星制+爱心图标+提交前校验是否 ≥2”,又得大改。真正高复用的组件,props 必须覆盖这些场景:
-
value(Number)、max(Number)、step(Number,默认 1)——这仨决定数值逻辑,缺一不可 -
icon(String,支持'star'/'heart'/'fire'),内部用v-if分支加载对应uni-icons -
size(String,如"28rpx"),不是固定 px,适配不同屏幕密度 -
showText(Boolean)和textMap(Object,如{1: '很差', 5: '超赞'})——文字提示不是写死在组件里,而是由业务传入 - 别漏掉
on-change和on-touch-end两个事件,前者用于表单联动,后者用于防抖后最终确认
最后提醒一句:所有自定义组件,v-model 绑定的变量必须初始化为 null 或具体数字,不能是 undefined,否则首次点击会触发 Vue 类型警告,且 0 分无法提交——因为 if (!score) 会把合法的 0 当成未选。


















