RatingComponent.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <template>
  2. <view class="rating-single">
  3. <text class="rating-label" v-if="label">{{ label }}</text>
  4. <view class="stars" @click.stop="handleClick">
  5. <!-- 修复:v-for 循环从 0 到 maxScore,共显示 maxScore 个星星 -->
  6. <text class="star" :class="{ active: currentScore >= index }" v-for="index in maxScore" :key="index"
  7. :data-index="index">★</text>
  8. </view>
  9. <text class="rating-text" v-if="showText">{{ getRatingText(currentScore) }}</text>
  10. </view>
  11. </template>
  12. <script>
  13. export default {
  14. name: "RatingSingle",
  15. model: {
  16. prop: "value",
  17. event: "change"
  18. },
  19. props: {
  20. label: {
  21. type: String,
  22. default: ""
  23. },
  24. value: {
  25. type: Number,
  26. default: 0
  27. },
  28. maxScore: {
  29. type: Number,
  30. default: 5
  31. },
  32. showText: {
  33. type: Boolean,
  34. default: false
  35. },
  36. textMap: {
  37. type: Array,
  38. default () {
  39. return ['非常不满意', '不满意', '一般', '满意', '非常满意'];
  40. }
  41. }
  42. },
  43. computed: {
  44. currentScore() {
  45. return Math.min(Math.max(this.value, 0), this.maxScore);
  46. }
  47. },
  48. methods: {
  49. getRatingText(score) {
  50. console.log(score, 'score')
  51. const index = Math.floor(score) - 1;
  52. return this.textMap[index] || "";
  53. },
  54. handleClick(e) {
  55. const target = e.target;
  56. const score = parseInt(target.dataset.index);
  57. if (!isNaN(score) && score >= 1 && score <= this.maxScore) {
  58. this.$emit("change", score);
  59. }
  60. }
  61. }
  62. };
  63. </script>
  64. <style scoped>
  65. .rating-single {
  66. display: flex;
  67. align-items: center;
  68. margin: 10px 0;
  69. }
  70. .rating-label {
  71. width: 80px;
  72. text-align: right;
  73. margin-right: 10px;
  74. color: #333;
  75. }
  76. .stars {
  77. display: flex;
  78. cursor: pointer;
  79. }
  80. .star {
  81. font-size: 20px;
  82. color: #e6e6e6;
  83. margin-right: 3px;
  84. transition: color 0.2s;
  85. }
  86. .star.active {
  87. /* color: #ffd700; */
  88. color: rgb(255, 202, 62);
  89. }
  90. .rating-text {
  91. margin-left: 8px;
  92. color: #666;
  93. }
  94. </style>