uni-rate.vue 2.9 KB

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