index.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <el-scrollbar class="z-1 min-h-30px" wrap-class="w-full" ref="containerRef">
  3. <div
  4. class="flex flex-row text-12px"
  5. :style="{
  6. gap: `${property.space}px`,
  7. width: scrollbarWidth
  8. }"
  9. >
  10. <div
  11. class="box-content"
  12. :style="{
  13. background: property.bgImg
  14. ? `url(${property.bgImg}) 100% center / 100% 100% no-repeat`
  15. : '#fff',
  16. width: `${couponWidth}px`,
  17. color: property.textColor
  18. }"
  19. v-for="(coupon, index) in couponList"
  20. :key="index"
  21. >
  22. <!-- 布局1:1列-->
  23. <div v-if="property.columns === 1" class="m-l-16px flex flex-row justify-between p-8px">
  24. <div class="flex flex-col justify-evenly gap-4px">
  25. <!-- 优惠值 -->
  26. <CouponDiscount :coupon="coupon" />
  27. <!-- 优惠描述 -->
  28. <CouponDiscountDesc :coupon="coupon" />
  29. <!-- 有效期 -->
  30. <CouponValidTerm :coupon="coupon" />
  31. </div>
  32. <div class="flex flex-col justify-evenly">
  33. <div
  34. class="rounded-20px p-x-8px p-y-2px"
  35. :style="{
  36. color: property.button.color,
  37. background: property.button.bgColor
  38. }"
  39. >
  40. 立即领取
  41. </div>
  42. </div>
  43. </div>
  44. <!-- 布局2:2列-->
  45. <div
  46. v-else-if="property.columns === 2"
  47. class="m-l-16px flex flex-row justify-between p-8px"
  48. >
  49. <div class="flex flex-col justify-evenly gap-4px">
  50. <!-- 优惠值 -->
  51. <CouponDiscount :coupon="coupon" />
  52. <div>{{ coupon.name }}</div>
  53. </div>
  54. <div class="flex flex-col">
  55. <div
  56. class="h-full w-20px rounded-20px p-x-2px p-y-8px text-center"
  57. :style="{
  58. color: property.button.color,
  59. background: property.button.bgColor
  60. }"
  61. >
  62. 立即领取
  63. </div>
  64. </div>
  65. </div>
  66. <!-- 布局3:3列-->
  67. <div v-else class="flex flex-col items-center justify-around gap-4px p-4px">
  68. <!-- 优惠值 -->
  69. <CouponDiscount :coupon="coupon" />
  70. <div>{{ coupon.name }}</div>
  71. <div
  72. class="rounded-20px p-x-8px p-y-2px"
  73. :style="{
  74. color: property.button.color,
  75. background: property.button.bgColor
  76. }"
  77. >
  78. 立即领取
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. </el-scrollbar>
  84. </template>
  85. <script setup lang="ts">
  86. import { CouponCardProperty } from './config'
  87. import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
  88. import { CouponDiscount } from './component'
  89. import {
  90. CouponDiscountDesc,
  91. CouponValidTerm
  92. } from '@/components/DiyEditor/components/mobile/CouponCard/component'
  93. /** 商品卡片 */
  94. defineOptions({ name: 'CouponCard' })
  95. // 定义属性
  96. const props = defineProps<{ property: CouponCardProperty }>()
  97. // 商品列表
  98. const couponList = ref<CouponTemplateApi.CouponTemplateVO[]>([])
  99. watch(
  100. () => props.property.couponIds,
  101. async () => {
  102. if (props.property.couponIds?.length > 0) {
  103. couponList.value = await CouponTemplateApi.getCouponTemplateList(props.property.couponIds)
  104. }
  105. },
  106. {
  107. immediate: true,
  108. deep: true
  109. }
  110. )
  111. // 手机宽度
  112. const phoneWidth = ref(375)
  113. // 容器
  114. const containerRef = ref()
  115. // 滚动条宽度
  116. const scrollbarWidth = ref('100%')
  117. // 优惠券的宽度
  118. const couponWidth = ref(375)
  119. // 计算布局参数
  120. watch(
  121. () => [props.property, phoneWidth, couponList.value.length],
  122. () => {
  123. // 每列的宽度为:(总宽度 - 间距 * (列数 - 1))/ 列数
  124. couponWidth.value =
  125. (phoneWidth.value * 0.95 - props.property.space * (props.property.columns - 1)) /
  126. props.property.columns
  127. // 显示滚动条
  128. scrollbarWidth.value = `${
  129. couponWidth.value * couponList.value.length +
  130. props.property.space * (couponList.value.length - 1)
  131. }px`
  132. },
  133. { immediate: true, deep: true }
  134. )
  135. onMounted(() => {
  136. // 提取手机宽度
  137. phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375
  138. })
  139. </script>
  140. <style scoped lang="scss"></style>