鸿蒙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 项目提供实用参考。


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

相关推荐
二蛋和他的大花2 分钟前
鸿蒙运动项目开发:项目运行环境切换器
harmonyos
狂团商城小师妹18 分钟前
设备巡检系统小程序ThinkPHP+UniApp
微信·微信小程序·小程序·uni-app·微信公众平台
Burt1 小时前
#🎉 unibest 3.0 发布了!看看都更新了啥好用的功能\~
前端·uni-app
深海的鲸同学luvi1 小时前
【HarmonyOS 5】应用更新功能详解
harmonyos
O3 小时前
鸿蒙应用开发—功耗优化(后台任务篇)
harmonyos
moxiaoran57534 小时前
uni-app项目实战笔记17--获取系统信息getSystemInfo状态栏和胶囊按钮
笔记·uni-app
小汽车滴滴5 小时前
碳中和时代的家电革命,从华为智选IAM看科技企业的环保担当
科技·华为
运维小贺6 小时前
华为和H3C服务器配置远控管理地址
运维·服务器·华为
谷雪_6586 小时前
学习华为 ensp 的学习心得体会
网络·学习·华为·网络工程·ensp
半路下车9 小时前
【Harmony OS 5】UNIapp在教育类应用中的实践与ArkTS实现
深度学习·uni-app·harmonyos