鸿蒙OS&UniApp 制作个性化的评分星级组件#三方框架 #Uniapp

UniApp 制作个性化的评分星级组件

在移动应用开发中,评分星级组件(Rating Star)是用户交互和反馈的重要工具,广泛应用于电商、外卖、内容社区等场景。一个美观、易用、可定制的评分组件,不仅能提升用户体验,还能增强产品的互动性。随着 HarmonyOS(鸿蒙)生态的不断壮大,如何用 UniApp 实现一个兼容鸿蒙的个性化评分星级组件,成为许多开发者关注的话题。本文将结合实际项目经验,详细讲解如何用 UniApp 制作一个灵活、可扩展、适配鸿蒙的评分星级组件。

为什么要自定义评分星级组件?

虽然市面上有一些现成的评分组件,但在实际项目中,往往会遇到如下需求:

  • 支持半星、整星、可自定义星星数量;
  • 支持自定义星星图标、颜色、大小、动画效果;
  • 兼容多端,尤其是 HarmonyOS 设备的适配和体验优化;
  • 支持只读、可编辑、带提示文字等多种模式。

自定义组件不仅能满足个性化需求,还能提升整体产品体验。

组件设计思路

设计一个评分星级组件,需要考虑以下几个方面:

  1. 星星数量与分值:支持自定义星星数量、当前分值、最小步长(如半星)。
  2. 交互体验:支持点击、滑动选择分数,动画反馈。
  3. 样式定制:支持自定义图标、颜色、大小、间距等。
  4. 鸿蒙适配:在鸿蒙端保证手势、动画、图标渲染等能力正常。
  5. 易用性与扩展性:props 设计合理,便于业务集成和后续扩展。

组件实现

我们以一个通用的 RatingStar 组件为例,支持自定义星星数量、分值、颜色、大小、只读等。

1. 组件结构

components/rating-star/rating-star.vue 下新建组件:

vue 复制代码
<template>
  <view class="rating-star" :style="{ fontSize: size }">
    <view
      v-for="(star, idx) in starCount"
      :key="idx"
      class="star-item"
      @touchstart="onTouch(idx, $event)"
      @click="onClick(idx, $event)"
    >
      <text
        :class="getStarClass(idx)"
        :style="{ color: getStarColor(idx) }"
      >
        {{ getStarIcon(idx) }}
      </text>
    </view>
    <text v-if="showText" class="rating-text">{{ displayText }}</text>
  </view>
</template>

<script>
export default {
  name: 'RatingStar',
  props: {
    value: {
      type: Number,
      default: 0
    },
    starCount: {
      type: Number,
      default: 5
    },
    allowHalf: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: '48rpx'
    },
    color: {
      type: String,
      default: '#ffd21e'
    },
    voidColor: {
      type: String,
      default: '#e5e5e5'
    },
    icon: {
      type: String,
      default: '★'
    },
    voidIcon: {
      type: String,
      default: '☆'
    },
    readonly: {
      type: Boolean,
      default: false
    },
    showText: {
      type: Boolean,
      default: false
    },
    texts: {
      type: Array,
      default: () => ['很差', '较差', '一般', '满意', '非常满意']
    }
  },
  data() {
    return {
      innerValue: this.value
    };
  },
  watch: {
    value(val) {
      this.innerValue = val;
    }
  },
  computed: {
    displayText() {
      if (!this.showText) return '';
      let idx = Math.ceil(this.innerValue) - 1;
      return this.texts[idx] || '';
    }
  },
  methods: {
    getStarClass(idx) {
      if (this.allowHalf && this.innerValue - idx > 0 && this.innerValue - idx < 1) {
        return 'star-half';
      }
      return this.innerValue > idx ? 'star-full' : 'star-void';
    },
    getStarColor(idx) {
      return this.innerValue > idx ? this.color : this.voidColor;
    },
    getStarIcon(idx) {
      if (this.allowHalf && this.innerValue - idx > 0 && this.innerValue - idx < 1) {
        return this.icon; // 可扩展为半星图标
      }
      return this.innerValue > idx ? this.icon : this.voidIcon;
    },
    onTouch(idx, e) {
      if (this.readonly) return;
      if (this.allowHalf) {
        const touch = e.touches[0];
        const rect = e.currentTarget.getBoundingClientRect();
        const isHalf = touch.clientX - rect.left < rect.width / 2;
        this.innerValue = isHalf ? idx + 0.5 : idx + 1;
      } else {
        this.innerValue = idx + 1;
      }
      this.$emit('input', this.innerValue);
      this.$emit('change', this.innerValue);
    },
    onClick(idx, e) {
      if (this.readonly) return;
      if (!this.allowHalf) {
        this.innerValue = idx + 1;
        this.$emit('input', this.innerValue);
        this.$emit('change', this.innerValue);
      }
    }
  }
};
</script>

<style scoped>
.rating-star {
  display: flex;
  align-items: center;
}
.star-item {
  margin-right: 8rpx;
  user-select: none;
}
.star-full {
  color: #ffd21e;
  transition: color 0.2s;
}
.star-void {
  color: #e5e5e5;
  transition: color 0.2s;
}
.star-half {
  color: #ffd21e;
  position: relative;
}
.rating-text {
  margin-left: 16rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

2. 组件使用示例

在页面中引用并使用 RatingStar 组件,实现评分交互:

vue 复制代码
<template>
  <view class="demo-rating">
    <rating-star v-model="score" :starCount="5" :allowHalf="true" :showText="true" />
    <text class="score-text">当前评分:{{ score }}</text>
    <rating-star :value="4" :starCount="7" color="#ff4d4f" voidColor="#eee" :readonly="true" :showText="true" :texts="['极差','很差','一般','良好','满意','优秀','满分']" />
  </view>
</template>

<script>
import RatingStar from '@/components/rating-star/rating-star.vue';

export default {
  components: { RatingStar },
  data() {
    return {
      score: 3.5
    };
  }
};
</script>

<style scoped>
.demo-rating {
  padding: 40rpx;
}
.score-text {
  margin-top: 24rpx;
  font-size: 32rpx;
  color: #333;
}
</style>

3. HarmonyOS 适配与优化建议

  • 手势体验:鸿蒙端对 touch/click 事件支持良好,半星交互流畅。建议在真机多端测试。
  • 图标自定义:可用 SVG、图片等自定义星星图标,提升视觉效果。
  • 动画优化:可结合 CSS 动画或帧动画,提升评分时的动感体验。
  • UI 细节 :鸿蒙设备分辨率多样,建议用 vw/rpx 单位自适应。
  • 无障碍支持:可为星星添加 aria-label,提升可访问性。

4. 实际案例与体验优化

在某鸿蒙快应用项目中,评分星级组件用于商品评价、内容打分等场景,结合后端接口实现评分统计和展示。实际开发中还可结合以下优化:

  • 支持自定义提示文字、动态颜色;
  • 评分后弹窗感谢或引导评论;
  • 只读模式下支持展示历史评分、平均分等;
  • 结合表单校验,评分为必填项时高亮提示。

总结

基于 UniApp 的评分星级组件方案,既能兼容 HarmonyOS 生态,也能满足多端统一开发需求。通过灵活的 props 设计、交互优化和样式定制,可以为用户带来高效、愉悦的评分体验。希望本文能为你的鸿蒙/UniApp 项目提供实用参考。


如有问题或更好的实现思路,欢迎留言交流!

相关推荐
moxiaoran57532 小时前
uni-app学习笔记十五-vue3页面生命周期(二)
笔记·学习·uni-app
不爱吃饭爱吃菜4 小时前
uniapp小程序开发,判断跳转页面是否需要登录方法封装
开发语言·前端·javascript·vue.js·uni-app
lqj_本人4 小时前
鸿蒙OS&UniApp 实现自定义的侧边栏菜单组件#三方框架 #Uniapp
华为·uni-app·harmonyos
声声codeGrandMaster4 小时前
uni-app开发特殊社交APP
小程序·uni-app·web app
Vence08155 小时前
Flutter3.22适配运行鸿蒙系统问题记录
flutter·华为·harmonyos·鸿蒙
郑知鱼9 小时前
【拥抱鸿蒙】Flutter+Cursor轻松打造HarmonyOS应用(二)
flutter·华为·harmonyos·鸿蒙·cursor·移动端·鸿蒙next·ohos
xmweisi0210 小时前
【华为战报】4月、5月 HCIP考试战报!
华为
二蛋和他的大花12 小时前
HarmonyOS运动开发:如何绘制运动速度轨迹
harmonyos
hunzi_116 小时前
uniapp好不好
uni-app
lqj_本人16 小时前
鸿蒙OS&UniApp 开发支持图片和视频的多媒体展示组件#三方框架 #Uniapp
uni-app·音视频·harmonyos