s-score-block.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <view>
  3. <view
  4. v-if="mode === 1 && state.scoreList.length"
  5. class="goods-md-wrap ss-flex ss-flex-wrap ss-col-top"
  6. >
  7. <view class="goods-list-box">
  8. <view
  9. class="left-list"
  10. :style="[{ paddingRight: data.space + 'rpx', marginBottom: data.space + 'px' }]"
  11. v-for="item in state.leftScoreList"
  12. :key="item.id"
  13. >
  14. <s-score-card
  15. class="goods-md-box"
  16. size="md"
  17. :goodsFields="goodsFields"
  18. :data="item"
  19. :titleColor="goodsFields.title?.color"
  20. :subTitleColor="goodsFields.subtitle.color"
  21. :topRadius="data.borderRadiusTop"
  22. :bottomRadius="data.borderRadiusBottom"
  23. :titleWidth="330 - marginLeft - marginRight"
  24. @click="sheep.$router.go('/pages/goods/score', { id: item.id })"
  25. @getHeight="mountMasonry($event, 'left')"
  26. >
  27. <template v-slot:cart>
  28. <button class="ss-reset-button cart-btn" :style="[buyStyle]">
  29. {{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
  30. </button>
  31. </template>
  32. </s-score-card>
  33. </view>
  34. </view>
  35. <view class="goods-list-box">
  36. <view
  37. class="right-list"
  38. :style="[{ paddingLeft: data.space + 'rpx', marginBottom: data.space + 'px' }]"
  39. v-for="item in state.rightScoreList"
  40. :key="item.id"
  41. >
  42. <s-score-card
  43. class="goods-md-box"
  44. size="md"
  45. :goodsFields="goodsFields"
  46. :data="item"
  47. :titleColor="goodsFields.title?.color"
  48. :subTitleColor="goodsFields.subtitle.color"
  49. :topRadius="data.borderRadiusTop"
  50. :bottomRadius="data.borderRadiusBottom"
  51. :titleWidth="330 - marginLeft - marginRight"
  52. @click="sheep.$router.go('/pages/goods/score', { id: item.id })"
  53. @getHeight="mountMasonry($event, 'right')"
  54. >
  55. <template v-slot:cart>
  56. <button class="ss-reset-button cart-btn" :style="[buyStyle]">
  57. {{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
  58. </button>
  59. </template>
  60. </s-score-card>
  61. </view>
  62. </view>
  63. <!-- <view class="goods-hack" v-if="state.scoreList.length % 2 == 1" style="width: 345rpx"></view> -->
  64. </view>
  65. <view v-if="mode === 2 && state.scoreList.length" class="goods-lg-box">
  66. <view
  67. class="goods-box"
  68. :style="[{ marginBottom: data.space + 'px' }]"
  69. v-for="item in state.scoreList"
  70. :key="item.id"
  71. >
  72. <s-score-card
  73. class="goods-card"
  74. size="lg"
  75. :goodsFields="goodsFields"
  76. :data="item"
  77. :titleColor="goodsFields.title?.color"
  78. :subTitleColor="goodsFields.subtitle.color"
  79. :topRadius="data.borderRadiusTop"
  80. :bottomRadius="data.borderRadiusBottom"
  81. @tap="sheep.$router.go('/pages/goods/score', { id: item.id })"
  82. >
  83. <template v-slot:cart>
  84. <button class="ss-reset-button cart-btn" :style="[buyStyle]">
  85. {{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
  86. </button>
  87. </template>
  88. </s-score-card>
  89. </view>
  90. </view>
  91. </view>
  92. </template>
  93. <script setup>
  94. import { computed, reactive, onMounted } from 'vue';
  95. import sheep from '@/sheep';
  96. const state = reactive({
  97. scoreList: [],
  98. leftScoreList: [],
  99. rightScoreList: [],
  100. });
  101. const props = defineProps({
  102. data: {
  103. type: Object,
  104. default() {},
  105. },
  106. styles: {
  107. type: Object,
  108. default() {},
  109. },
  110. });
  111. const { mode, buyNowStyle, goodsFields, goodsIds } = props.data ?? {};
  112. const { marginLeft, marginRight } = props.styles ?? {};
  113. async function getScoreListByIds(ids) {
  114. let { data } = await sheep.$api.app.scoreShop.ids({ ids });
  115. return data;
  116. }
  117. onMounted(async () => {
  118. state.scoreList = await getScoreListByIds(goodsIds.join(','));
  119. if (mode === 1) {
  120. mountMasonry();
  121. }
  122. });
  123. // 加载瀑布流
  124. let count = 0;
  125. let leftHeight = 0;
  126. let rightHeight = 0;
  127. function mountMasonry(height = 0, where = 'left') {
  128. if (!state.scoreList[count]) return;
  129. if (where === 'left') leftHeight += height;
  130. if (where === 'right') rightHeight += height;
  131. if (leftHeight <= rightHeight) {
  132. state.leftScoreList.push(state.scoreList[count]);
  133. } else {
  134. state.rightScoreList.push(state.scoreList[count]);
  135. }
  136. count++;
  137. }
  138. // 购买按钮样式
  139. const buyStyle = computed(() => {
  140. if (buyNowStyle.mode == 1) {
  141. // button
  142. return {
  143. background: `linear-gradient(to right, ${buyNowStyle.color1}, ${buyNowStyle.color2})`,
  144. };
  145. }
  146. if (buyNowStyle.mode == 2) {
  147. // image
  148. return {
  149. width: '54rpx',
  150. height: '54rpx',
  151. background: `url(${sheep.$url.cdn(buyNowStyle.src)}) no-repeat`,
  152. backgroundSize: '100% 100%',
  153. };
  154. }
  155. });
  156. </script>
  157. <style lang="scss" scoped>
  158. .goods-md-wrap {
  159. width: 100%;
  160. }
  161. .goods-list-box {
  162. width: 50%;
  163. box-sizing: border-box;
  164. .left-list {
  165. &:nth-last-child(1) {
  166. margin-bottom: 0 !important;
  167. }
  168. }
  169. }
  170. .goods-box {
  171. &:nth-last-of-type(1) {
  172. margin-bottom: 0 !important;
  173. }
  174. }
  175. .goods-md-box,
  176. .goods-sl-box,
  177. .goods-lg-box {
  178. position: relative;
  179. .cart-btn {
  180. position: absolute;
  181. bottom: 10rpx;
  182. right: 20rpx;
  183. z-index: 11;
  184. height: 50rpx;
  185. line-height: 50rpx;
  186. padding: 0 20rpx;
  187. border-radius: 25rpx;
  188. font-size: 24rpx;
  189. color: #fff;
  190. }
  191. }
  192. </style>