rf-rate.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <view class="uni-rate">
  3. <view
  4. :key="index"
  5. :style="{ marginLeft: margin + 'px' }"
  6. @tap="_onClick(index)"
  7. class="uni-rate__icon"
  8. v-for="(star, index) in stars"
  9. >
  10. <text
  11. class="iconfont iconstar"
  12. :style="{ color: isFill ? '#eee' : '#ececec' }"
  13. ></text>
  14. <!-- #ifdef APP-NVUE -->
  15. <view
  16. :style="{
  17. width: (star.activeWitch.replace('%', '') * size) / 100 + 'px'
  18. }"
  19. class="uni-rate__icon-on"
  20. >
  21. <text class="iconfont iconstar" :style="{ color: activeColor }"></text>
  22. </view>
  23. <!-- #endif -->
  24. <!-- #ifndef APP-NVUE -->
  25. <view
  26. :style="{ width: star.activeWitch, top: -size / 2 - 1 + 'px' }"
  27. class="uni-rate__icon-on"
  28. >
  29. <text class="iconfont iconstar" :style="{ color: activeColor }"></text>
  30. </view>
  31. <!-- #endif -->
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. export default {
  37. name: 'rfRate',
  38. props: {
  39. isFill: {
  40. // 星星的类型,是否镂空
  41. type: [Boolean, String],
  42. default: true
  43. },
  44. color: {
  45. // 星星的颜色
  46. type: String,
  47. default: '#ececec'
  48. },
  49. activeColor: {
  50. // 星星选中状态颜色
  51. type: String,
  52. default: '#ffca3e'
  53. },
  54. size: {
  55. // 星星的大小
  56. type: [Number, String],
  57. default: 24
  58. },
  59. value: {
  60. // 当前评分
  61. type: [Number, String],
  62. default: 0
  63. },
  64. index: {
  65. // 当前评分
  66. type: Number,
  67. default: 1
  68. },
  69. max: {
  70. // 最大评分
  71. type: [Number, String],
  72. default: 5
  73. },
  74. margin: {
  75. // 星星的间距
  76. type: [Number, String],
  77. default: 0
  78. },
  79. disabled: {
  80. // 是否可点击
  81. type: [Boolean, String],
  82. default: false
  83. }
  84. },
  85. data() {
  86. return {
  87. valueSync: ''
  88. };
  89. },
  90. computed: {
  91. stars() {
  92. const value = this.valueSync ? this.valueSync : 0;
  93. const starList = [];
  94. const floorValue = Math.floor(value);
  95. const ceilValue = Math.ceil(value);
  96. // console.log("ceilValue: " + ceilValue);
  97. // console.log("floorValue: " + floorValue);
  98. for (let i = 0; i < this.max; i++) {
  99. if (floorValue > i) {
  100. starList.push({
  101. activeWitch: '100%'
  102. });
  103. } else if (ceilValue - 1 === i) {
  104. starList.push({
  105. activeWitch: (value - floorValue) * 100 + '%'
  106. });
  107. } else {
  108. starList.push({
  109. activeWitch: '0'
  110. });
  111. }
  112. }
  113. return starList;
  114. }
  115. },
  116. created() {
  117. this.valueSync = Number(this.value);
  118. },
  119. methods: {
  120. _onClick(index) {
  121. if (this.disabled) {
  122. return;
  123. }
  124. this.valueSync = index + 1;
  125. this.$emit('change', {
  126. value: this.valueSync,
  127. index: this.index
  128. });
  129. }
  130. }
  131. };
  132. </script>
  133. <style lang="scss" scoped>
  134. .uni-rate {
  135. /* #ifndef APP-NVUE */
  136. display: flex;
  137. /* #endif */
  138. line-height: 0;
  139. font-size: 0;
  140. flex-direction: row;
  141. }
  142. .iconfont {
  143. font-size: $font-lg + 4upx;
  144. }
  145. .uni-rate__icon {
  146. position: relative;
  147. line-height: 0;
  148. font-size: 0;
  149. }
  150. .uni-rate__icon-on {
  151. overflow: hidden;
  152. position: absolute;
  153. top: 0;
  154. left: 0;
  155. line-height: 1;
  156. text-align: left;
  157. }
  158. </style>