sh-hot-goods.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <template>
  2. <!-- 为你推荐 -->
  3. <view class="hot-goods u-m-b-10 u-p-x-16">
  4. <view class="u-waterfall" v-if="goodsType === 1">
  5. <view id="u-left-column" class="u-column">
  6. <view class="goods-item u-m-b-16 u-flex u-row-center u-col-center" v-for="leftGoods in leftList" :key="leftGoods.id">
  7. <shopro-goods-card
  8. :detail="leftGoods"
  9. :type="leftGoods.activity_type"
  10. :image="leftGoods.image"
  11. :title="leftGoods.title"
  12. :subtitle="leftGoods.subtitle"
  13. :price="leftGoods.price"
  14. :originPrice="leftGoods.original_price"
  15. :sales="leftGoods.sales"
  16. :tagTextList="leftGoods.activity_discounts_tags"
  17. @click="$Router.push({ path: '/pages/goods/detail', query: { id: leftGoods.id } })"
  18. ></shopro-goods-card>
  19. </view>
  20. </view>
  21. <view id="u-right-column" class="u-column">
  22. <view class="goods-item u-m-b-16 u-flex u-row-center u-col-center" v-for="rightGoods in rightList" :key="rightGoods.id">
  23. <shopro-goods-card
  24. :detail="rightGoods"
  25. :type="rightGoods.activity_type"
  26. :image="rightGoods.image"
  27. :title="rightGoods.title"
  28. :subtitle="rightGoods.subtitle"
  29. :price="rightGoods.price"
  30. :originPrice="rightGoods.original_price"
  31. :sales="rightGoods.sales"
  32. :tagTextList="rightGoods.activity_discounts_tags"
  33. @click="$Router.push({ path: '/pages/goods/detail', query: { id: rightGoods.id } })"
  34. ></shopro-goods-card>
  35. </view>
  36. </view>
  37. </view>
  38. <!-- m -->
  39. <view class="big-card-wrap u-p-10" v-if="goodsType === 2">
  40. <block v-for="item in goodsList" :key="item.id">
  41. <sh-goods-card
  42. :detail="item"
  43. :type="item.activity_type"
  44. :image="item.image"
  45. :title="item.title"
  46. :subtitle="item.subtitle"
  47. :price="item.price"
  48. :originPrice="item.original_price"
  49. :sales="item.sales"
  50. :tagTextList="item.activity_discounts_tags"
  51. @click="$Router.push({ path: '/pages/goods/detail', query: { id: item.id } })"
  52. ></sh-goods-card>
  53. </block>
  54. </view>
  55. <button v-show="total > perPage" class="u-reset-button refresh-btn u-m-y-20 u-flex u-col-center u-row-center" @tap.stop="loadMore">
  56. <text class="u-m-r-6 u-iconfont uicon-reload" style="font-size: 28rpx;color: #999" :class="{ 'refresh-active': isRefresh }"></text>
  57. {{ listParams.page >= lastPage ? '收起' : '加载更多' }}
  58. </button>
  59. </view>
  60. </template>
  61. <script>
  62. /**
  63. * 自定义之为你推荐
  64. * @property {Object} detail - 推荐商品信息
  65. */
  66. import shGoodsCard from './sh-goods-card.vue';
  67. export default {
  68. components: {
  69. shGoodsCard
  70. },
  71. data() {
  72. return {
  73. listParams: {
  74. page: 1
  75. }, //当前分页
  76. lastPage: 1, //总分页
  77. total: 0, //总商品数
  78. perPage: 0, //单页商品数
  79. goodsList: [],
  80. isRefresh: false,
  81. // 瀑布流 350-330
  82. addTime: 100, //排序间隙时间
  83. leftHeight: 0,
  84. rightHeight: 0,
  85. leftList: [],
  86. rightList: [],
  87. tempList: [],
  88. goodsType: this.detail.style // 商品模板
  89. };
  90. },
  91. props: {
  92. detail: {
  93. type: Object,
  94. default: () => {}
  95. }
  96. },
  97. created() {
  98. if (this.detail.id) {
  99. this.listParams.category_id = this.detail.id;
  100. this.getGoodsList();
  101. }
  102. if (this.detail.ids) {
  103. this.listParams.goods_ids = this.detail.ids;
  104. this.getGoodsList();
  105. }
  106. },
  107. methods: {
  108. // 瀑布流相关
  109. async splitData() {
  110. if (!this.tempList.length) return;
  111. let item = this.tempList[0];
  112. if (!item) return;
  113. // 分左右
  114. if (this.leftHeight < this.rightHeight) {
  115. this.leftHeight += item.activity_discounts_tags?.length ? 350 : 330;
  116. this.leftList.push(item);
  117. } else if (this.leftHeight > this.rightHeight) {
  118. this.rightHeight += item.activity_discounts_tags?.length ? 350 : 330;
  119. this.rightList.push(item);
  120. } else {
  121. this.leftHeight += item.activity_discounts_tags?.length ? 350 : 330;
  122. this.leftList.push(item);
  123. }
  124. // 移除临时列表的第一项,如果临时数组还有数据,继续循环
  125. this.tempList.splice(0, 1);
  126. if (this.tempList.length) {
  127. setTimeout(() => {
  128. this.splitData();
  129. }, this.addTime);
  130. }
  131. },
  132. clear() {
  133. this.leftList = [];
  134. this.rightList = [];
  135. this.leftHeight = 0;
  136. this.rightHeight = 0;
  137. this.tempList = [];
  138. },
  139. // 商品列表
  140. getGoodsList() {
  141. let that = this;
  142. that.$http('goods.lists', this.listParams).then(res => {
  143. if (res.code === 1) {
  144. this.lastPage = res.data.last_page;
  145. this.total = res.data.total;
  146. this.perPage = res.data.per_page;
  147. this.isRefresh = false;
  148. that.goodsList = [...that.goodsList, ...res.data.data];
  149. that.tempList = res.data.data;
  150. that.goodsList.length && that.splitData();
  151. }
  152. });
  153. },
  154. // 加载更多
  155. loadMore() {
  156. if (!this.isRefresh) {
  157. // 加载更多
  158. if (this.listParams.page < this.lastPage) {
  159. this.isRefresh = true;
  160. this.listParams.page += 1;
  161. this.getGoodsList();
  162. } else {
  163. // 重置为1页数据
  164. this.listParams.page = 1;
  165. this.lastPage = 1;
  166. this.goodsList = [];
  167. this.clear();
  168. this.getGoodsList();
  169. }
  170. }
  171. }
  172. }
  173. };
  174. </script>
  175. <style lang="scss">
  176. @mixin vue-flex($direction: row) {
  177. /* #ifndef APP-NVUE */
  178. display: flex;
  179. flex-direction: $direction;
  180. /* #endif */
  181. }
  182. .u-waterfall {
  183. @include vue-flex;
  184. flex-direction: row;
  185. align-items: flex-start;
  186. }
  187. .u-column {
  188. @include vue-flex;
  189. flex: 1;
  190. flex-direction: column;
  191. height: auto;
  192. }
  193. .u-image {
  194. width: 100%;
  195. }
  196. // 为你推荐
  197. .hot-goods {
  198. background: none;
  199. .refresh-btn {
  200. margin-left: 50%;
  201. transform: translateX(-50%);
  202. width: 156rpx;
  203. line-height: 50rpx;
  204. background: #ffffff;
  205. border-radius: 25rpx;
  206. font-size: 22rpx;
  207. font-weight: 500;
  208. color: #999999;
  209. white-space: nowrap;
  210. }
  211. .refresh-active {
  212. transform: rotate(360deg);
  213. transition: all linear 0.5s;
  214. }
  215. }
  216. </style>