ProductItem.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <div>
  3. <div>
  4. <slot name="top"></slot>
  5. </div>
  6. <div
  7. :style="[{ borderRadius: radius + 'px', marginBottom: marginBottom + 'px' }]"
  8. class="ss-order-card-warp flex items-stretch justify-between bg-white"
  9. >
  10. <div class="img-box mr-24px">
  11. <el-image :src="img" class="order-img" fit="contain" @click="imagePrediv(img)" />
  12. </div>
  13. <div
  14. :style="[{ width: titleWidth ? titleWidth + 'px' : '' }]"
  15. class="box-right flex flex-col justify-between"
  16. >
  17. <div v-if="title" class="title-text ss-line-2">{{ title }}</div>
  18. <div v-if="skuString" class="spec-text mt-8px mb-12px">{{ skuString }}</div>
  19. <div class="groupon-box">
  20. <slot name="groupon"></slot>
  21. </div>
  22. <div class="flex">
  23. <div class="flex items-center">
  24. <div
  25. v-if="price && Number(price) > 0"
  26. :style="[{ color: priceColor }]"
  27. class="price-text flex items-center"
  28. >
  29. ¥{{ fenToYuan(price) }}
  30. </div>
  31. <div v-if="num" class="total-text flex items-center">x {{ num }}</div>
  32. <slot name="priceSuffix"></slot>
  33. </div>
  34. </div>
  35. <div class="tool-box">
  36. <slot name="tool"></slot>
  37. </div>
  38. <div>
  39. <slot name="rightBottom"></slot>
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <script lang="ts" setup>
  46. import { createImageViewer } from '@/components/ImageViewer'
  47. import { fenToYuan } from '@/utils'
  48. defineOptions({ name: 'ProductItem' })
  49. const props = defineProps({
  50. img: {
  51. type: String,
  52. default: 'https://img1.baidu.com/it/u=1601695551,235775011&fm=26&fmt=auto'
  53. },
  54. title: {
  55. type: String,
  56. default: ''
  57. },
  58. titleWidth: {
  59. type: Number,
  60. default: 0
  61. },
  62. skuText: {
  63. type: [String, Array],
  64. default: ''
  65. },
  66. price: {
  67. type: [String, Number],
  68. default: ''
  69. },
  70. priceColor: {
  71. type: [String],
  72. default: ''
  73. },
  74. num: {
  75. type: [String, Number],
  76. default: 0
  77. },
  78. score: {
  79. type: [String, Number],
  80. default: ''
  81. },
  82. radius: {
  83. type: [String],
  84. default: ''
  85. },
  86. marginBottom: {
  87. type: [String],
  88. default: ''
  89. }
  90. })
  91. /** SKU 展示字符串 */
  92. const skuString = computed(() => {
  93. if (!props.skuText) {
  94. return ''
  95. }
  96. if (typeof props.skuText === 'object') {
  97. return props.skuText.join(',')
  98. }
  99. return props.skuText
  100. })
  101. // TODO @puhui999:可以使用 preview-teleported
  102. /** 图预览 */
  103. const imagePrediv = (imgUrl: string) => {
  104. createImageViewer({
  105. urlList: [imgUrl]
  106. })
  107. }
  108. </script>
  109. <style lang="scss" scoped>
  110. .score-img {
  111. width: 36px;
  112. height: 36px;
  113. margin: 0 4px;
  114. }
  115. .ss-order-card-warp {
  116. padding: 20px;
  117. border-radius: 10px;
  118. background-color: #e2e2e2;
  119. .img-box {
  120. width: 164px;
  121. height: 164px;
  122. border-radius: 10px;
  123. overflow: hidden;
  124. .order-img {
  125. width: 164px;
  126. height: 164px;
  127. }
  128. }
  129. .box-right {
  130. flex: 1;
  131. // width: 500px;
  132. // height: 164px;
  133. position: relative;
  134. .tool-box {
  135. position: absolute;
  136. right: 0px;
  137. bottom: -10px;
  138. }
  139. }
  140. .title-text {
  141. font-size: 28px;
  142. font-weight: 500;
  143. line-height: 40px;
  144. }
  145. .spec-text {
  146. font-size: 24px;
  147. font-weight: 400;
  148. color: #999999;
  149. min-width: 0;
  150. overflow: hidden;
  151. text-overflow: ellipsis;
  152. display: -webkit-box;
  153. -webkit-line-clamp: 1;
  154. -webkit-box-orient: vertical;
  155. }
  156. .price-text {
  157. font-size: 24px;
  158. font-weight: 500;
  159. font-family: OPPOSANS;
  160. }
  161. .total-text {
  162. font-size: 24px;
  163. font-weight: 400;
  164. line-height: 24px;
  165. color: #999999;
  166. margin-left: 8px;
  167. }
  168. }
  169. .ss-line {
  170. min-width: 0;
  171. overflow: hidden;
  172. text-overflow: ellipsis;
  173. display: -webkit-box;
  174. -webkit-box-orient: vertical;
  175. &-1 {
  176. -webkit-line-clamp: 1;
  177. }
  178. &-2 {
  179. -webkit-line-clamp: 2;
  180. }
  181. }
  182. </style>