fs-badge.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <view class="fs-badge">
  3. <slot></slot>
  4. <view
  5. v-if="dot"
  6. class="fs-badge-dot"
  7. :class="['bg-' + bgColorType, { absolute: slots.default }]"
  8. :style="{
  9. backgroundColor: bgColor
  10. }"
  11. ></view>
  12. <view
  13. v-else
  14. class="fs-badge-count"
  15. :class="['bg-' + bgColorType, { absolute: slots.default }]"
  16. :style="{
  17. backgroundColor: bgColor
  18. }"
  19. >
  20. <slot name="count">{{ value }}</slot>
  21. </view>
  22. </view>
  23. </template>
  24. <script>
  25. /**
  26. * 徽章组件
  27. * @description 徽章组件
  28. * @property {Number} count 数字
  29. * @property {Boolean} dot 是否显示圆点
  30. * @property {String} bgColor 背景颜色
  31. * @property {String} bgColorType = [primary | danger | warning | info | success] 背景颜色类型
  32. */
  33. export default {
  34. name: 'fs-badge'
  35. }
  36. </script>
  37. <script setup>
  38. import { computed, useSlots } from 'vue'
  39. const props = defineProps({
  40. dot: Boolean,
  41. count: Number,
  42. bgColor: String,
  43. bgColorType: {
  44. type: String,
  45. default: 'danger',
  46. validator(value) {
  47. return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
  48. }
  49. }
  50. })
  51. const value = computed(() => (props.count > 99 ? '99+' : props.count))
  52. const slots = useSlots()
  53. </script>
  54. <style lang="scss" scoped>
  55. .fs-badge {
  56. position: relative;
  57. display: inline-block;
  58. vertical-align: middle;
  59. &-dot {
  60. width: 16rpx;
  61. height: 16rpx;
  62. border-radius: 50%;
  63. top: -8rpx;
  64. right: -8rpx;
  65. z-index: 10;
  66. }
  67. &-count {
  68. color: #fff;
  69. font-size: 12px;
  70. font-weight: 500;
  71. padding: 0 6px;
  72. line-height: 36rpx;
  73. min-width: 36rpx;
  74. border-radius: 18rpx;
  75. text-align: center;
  76. box-sizing: border-box;
  77. white-space: nowrap;
  78. z-index: 10;
  79. &.absolute {
  80. top: 0;
  81. right: 0;
  82. transform: translate(50%, -50%) scale(0.8);
  83. }
  84. }
  85. .absolute {
  86. position: absolute;
  87. }
  88. }
  89. </style>