fs-rate.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. ></fs-icon>
  10. <view v-if="allowHalf && index < modelValue && index + 1 > modelValue" class="fs-rate-half">
  11. <view class="fs-rate-half-active" :style="{ width: size / 2 + 'rpx' }">
  12. <fs-icon :type="activeIcon" :color="activeColor" :size="iconSize" :source="source"></fs-icon>
  13. </view>
  14. <view class="fs-rate-half-inactive">
  15. <fs-icon :type="activeIcon" :color="inactiveColor" :size="iconSize" :source="source"></fs-icon>
  16. </view>
  17. </view>
  18. </view>
  19. </view>
  20. </template>
  21. <script>
  22. /**
  23. * 评分组件
  24. * @description 评分组件
  25. * @property {Number} count 图标数量
  26. * @property {String} activeColor 图标选中的颜色
  27. * @property {String} inactiveColor 图标未选中的颜色
  28. * @property {String} activeIcon 选中的图标
  29. * @property {String} inactiveIcon 未选中的图标
  30. * @property {String} size 图标大小(单位rpx)
  31. * @property {Boolean} allowHalf 是否允许半星
  32. * @property {Boolean} disabled 是否禁用
  33. * @property {String} source 图标来源
  34. * @event {Function} change change事件
  35. */
  36. export default {
  37. name: 'fs-rate'
  38. }
  39. </script>
  40. <script setup>
  41. import { computed } from 'vue'
  42. const props = defineProps({
  43. modelValue: {
  44. type: Number,
  45. default: 0
  46. },
  47. count: {
  48. type: Number,
  49. default: 5
  50. },
  51. activeColor: {
  52. type: String,
  53. default: '#F53F3F'
  54. },
  55. inactiveColor: {
  56. type: String,
  57. default: '#999999'
  58. },
  59. size: {
  60. type: Number,
  61. default: '40'
  62. },
  63. disabled: Boolean,
  64. activeIcon: {
  65. type: String,
  66. default: 'icon-star-fill'
  67. },
  68. inactiveIcon: {
  69. type: String,
  70. default: 'icon-star'
  71. },
  72. source: {
  73. type: String,
  74. default: 'inner'
  75. },
  76. allowHalf: Boolean
  77. })
  78. const emits = defineEmits(['update:modelValue', 'change'])
  79. const iconSize = computed(() => props.size + 'rpx')
  80. const handleClick = index => {
  81. if (!props.disabled) {
  82. emits('update:modelValue', index + 1)
  83. emits('change', index + 1)
  84. }
  85. }
  86. </script>
  87. <style lang="scss">
  88. .fs-rate {
  89. display: flex;
  90. &-item {
  91. position: relative;
  92. & + & {
  93. margin-left: 8rpx;
  94. }
  95. }
  96. &-half {
  97. position: absolute;
  98. left: 0;
  99. top: 0;
  100. z-index: 1;
  101. overflow: hidden;
  102. &-active {
  103. position: absolute;
  104. top: 0;
  105. left: 0;
  106. z-index: 1;
  107. overflow: hidden;
  108. }
  109. }
  110. }
  111. </style>