GroupAvatarStack.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <!--
  2. 拼团成员头像叠加
  3. 用途:团购详情「当前拼团中」卡片展示已参团头像 + 空位加号
  4. list: [{avatar,name}];groupSize 为成团总人数;用负 margin 叠加,禁用 gap
  5. -->
  6. <template>
  7. <view class="avatar-stack">
  8. <view
  9. v-for="(slot, index) in slots"
  10. :key="index"
  11. class="avatar-item"
  12. :class="{ first: index === 0, empty: slot.empty }"
  13. >
  14. <image
  15. v-if="!slot.empty"
  16. class="avatar-img"
  17. :src="slot.avatar | default_avatar"
  18. mode="aspectFill"
  19. />
  20. <view v-else class="avatar-empty">
  21. <text class="plus">+</text>
  22. </view>
  23. </view>
  24. </view>
  25. </template>
  26. <script>
  27. export default {
  28. name: 'GroupAvatarStack',
  29. props: {
  30. /** 已参团成员(已支付) */
  31. list: { type: Array, default: () => [] },
  32. /** 成团所需人数 */
  33. groupSize: { type: Number, default: 3 },
  34. /** 最多展示几个头像槽位 */
  35. max: { type: Number, default: 5 }
  36. },
  37. computed: {
  38. slots() {
  39. const size = Math.min(Number(this.groupSize) || 3, this.max)
  40. const members = Array.isArray(this.list) ? this.list : []
  41. const result = []
  42. for (let i = 0; i < size; i++) {
  43. const m = members[i]
  44. if (m) {
  45. result.push({
  46. empty: false,
  47. avatar: m.avatar || m.avatarUrl || ''
  48. })
  49. } else {
  50. result.push({ empty: true, avatar: '' })
  51. }
  52. }
  53. return result
  54. }
  55. }
  56. }
  57. </script>
  58. <style lang="scss" scoped>
  59. .avatar-stack {
  60. display: flex;
  61. flex-direction: row;
  62. align-items: center;
  63. }
  64. .avatar-item {
  65. width: 64upx;
  66. height: 64upx;
  67. border-radius: 50%;
  68. overflow: hidden;
  69. border: 4upx solid #fff;
  70. background: #fff;
  71. margin-left: -16upx;
  72. box-sizing: border-box;
  73. &.first {
  74. margin-left: 0;
  75. }
  76. }
  77. .avatar-img {
  78. width: 100%;
  79. height: 100%;
  80. display: block;
  81. }
  82. .avatar-empty {
  83. width: 100%;
  84. height: 100%;
  85. border-radius: 50%;
  86. border: 2upx dashed #ffb3c1;
  87. background: #fff5f7;
  88. display: flex;
  89. align-items: center;
  90. justify-content: center;
  91. box-sizing: border-box;
  92. }
  93. .plus {
  94. color: #ff6b8a;
  95. font-size: 32upx;
  96. line-height: 1;
  97. }
  98. </style>