fs-rate.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <template>
  2. <view class="fs-rate">
  3. <view class="fs-rate-item" @click="handleClick(index)" v-for="(item,index) in count" :key="index">
  4. <fs-icon
  5. :type="index < modelValue ? activeIcon : inactiveIcon"
  6. :color="index < modelValue ? activeColor : inactiveColor"
  7. :size="iconSize"
  8. :source="source"
  9. >
  10. </fs-icon>
  11. <view
  12. v-if="allowHalf && index < modelValue && (index + 1) > modelValue"
  13. class="fs-rate-half">
  14. <view class="fs-rate-half-active" :style="{width: size / 2 + 'rpx'}">
  15. <fs-icon
  16. :type="activeIcon"
  17. :color="activeColor"
  18. :size="iconSize"
  19. :source="source"
  20. >
  21. </fs-icon>
  22. </view>
  23. <view class="fs-rate-half-inactive">
  24. <fs-icon
  25. :type="activeIcon"
  26. :color="inactiveColor"
  27. :size="iconSize"
  28. :source="source"
  29. >
  30. </fs-icon>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. </template>
  36. <script>
  37. export default {
  38. name: 'fs-rate',
  39. }
  40. </script>
  41. <script setup>
  42. import { computed } from 'vue'
  43. const props = defineProps({
  44. modelValue: {
  45. type: Number,
  46. default: 0
  47. },
  48. count: {
  49. type: Number,
  50. default: 5
  51. },
  52. activeColor: {
  53. type: String,
  54. default: '#F53F3F'
  55. },
  56. inactiveColor: {
  57. type: String,
  58. default: '#999999'
  59. },
  60. size: {
  61. type: Number,
  62. default: '40'
  63. },
  64. disabled: Boolean,
  65. activeIcon: {
  66. type: String,
  67. default: 'icon-star-fill'
  68. },
  69. inactiveIcon: {
  70. type: String,
  71. default: 'icon-star'
  72. },
  73. source: {
  74. type: String,
  75. default: 'inner'
  76. },
  77. allowHalf: Boolean,
  78. })
  79. const emits = defineEmits(['update:modelValue', 'change'])
  80. const iconSize = computed(() =>props.size + 'rpx')
  81. const handleClick = index => {
  82. if (!props.disabled) {
  83. emits('update:modelValue', index + 1)
  84. emits('change', index + 1)
  85. }
  86. }
  87. </script>
  88. <style lang="scss">
  89. .fs-rate{
  90. display: flex;
  91. &-item{
  92. position: relative;
  93. & + &{
  94. margin-left: 8rpx;
  95. }
  96. }
  97. &-half{
  98. position: absolute;
  99. left: 0;
  100. top: 0;
  101. z-index: 1;
  102. overflow: hidden;
  103. &-active{
  104. position: absolute;
  105. top: 0;
  106. left: 0;
  107. z-index: 1;
  108. overflow: hidden;
  109. }
  110. }
  111. }
  112. </style>