uni-rate.vue 2.9 KB

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