list.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <!-- 商品列表 -->
  2. <template>
  3. <view class="list-box">
  4. <!-- 倒计时 -->
  5. <u-sticky ref="uSticky" bgColor="#f6f6f6" offsetTop="0">
  6. <view class="tip-list-box">
  7. <view class="tip-list u-flex-col u-flex-1 u-p-30">
  8. <view class="count-down-box u-flex u-col-center">
  9. <view class="u-m-r-10">{{ timeRule.title }}</view>
  10. <u-count-down
  11. v-if="timeRule.time"
  12. class="count-down-demo"
  13. :timestamp="timeRule.time / 1000"
  14. separator-color="#333 "
  15. bg-color="#FF0000 "
  16. ref="uCountDown"
  17. color="#fff"
  18. @end="getTime"
  19. autoplay
  20. ></u-count-down>
  21. </view>
  22. <view class="u-flex u-flex-1 u-col-center modal-item u-flex-wrap u-m-t-10" v-if="activityInfo.tags">
  23. <view class="title-tag cu-tag bg-red sm radius u-m-r-10 u-m-t-10" >{{ activityInfo.title }}</view>
  24. <view class="tag-box cu-tag line-red sm radius u-m-r-10 u-m-t-10" v-for="(tag, index) in activityInfo.tags" :key="tag">{{ tag }}</view>
  25. </view>
  26. </view>
  27. </view>
  28. </u-sticky>
  29. <!-- 商品列表 -->
  30. <view class="u-waterfall u-p-16" v-if="!isEmpty">
  31. <view id="u-left-column" class="u-column">
  32. <view class="goods-item u-m-b-16 u-flex u-row-center u-col-center" v-for="leftGoods in leftList" :key="leftGoods.id">
  33. <shopro-goods-card
  34. :detail="leftGoods"
  35. :type="leftGoods.activity_type"
  36. :image="leftGoods.image"
  37. :title="leftGoods.title"
  38. :subtitle="leftGoods.subtitle"
  39. :price="leftGoods.price"
  40. :originPrice="leftGoods.original_price"
  41. :sales="leftGoods.sales"
  42. :tagTextList="leftGoods.activity_discounts_tags"
  43. @click="$Router.push({ path: '/pages/goods/detail', query: { id: leftGoods.id } })"
  44. ></shopro-goods-card>
  45. </view>
  46. </view>
  47. <view id="u-right-column" class="u-column">
  48. <view class="goods-item u-m-b-16 u-flex u-row-center u-col-center" v-for="rightGoods in rightList" :key="rightGoods.id">
  49. <shopro-goods-card
  50. :detail="rightGoods"
  51. :type="rightGoods.activity_type"
  52. :image="rightGoods.image"
  53. :title="rightGoods.title"
  54. :subtitle="rightGoods.subtitle"
  55. :price="rightGoods.price"
  56. :originPrice="rightGoods.original_price"
  57. :sales="rightGoods.sales"
  58. :tagTextList="rightGoods.activity_discounts_tags"
  59. @click="$Router.push({ path: '/pages/goods/detail', query: { id: rightGoods.id } })"
  60. ></shopro-goods-card>
  61. </view>
  62. </view>
  63. </view>
  64. <!-- 缺省页 -->
  65. <shopro-empty v-if="isEmpty" :image="$IMG_URL + '/imgs/empty/empty_goods.png'" tipText="暂无该商品,还有更多好货等着你噢~"></shopro-empty>
  66. <!-- 加载更多 -->
  67. <u-loadmore v-show="goodsList.length" height="80rpx" :status="loadStatus" icon-type="flower" color="#ccc" />
  68. <!-- 登录弹窗 -->
  69. <shopro-auth-modal></shopro-auth-modal>
  70. </view>
  71. </template>
  72. <script>
  73. import { mapMutations, mapActions, mapState } from 'vuex';
  74. export default {
  75. components: {},
  76. data() {
  77. return {
  78. activityInfo: {},
  79. timeRule: {
  80. title: '',
  81. time: 0
  82. },
  83. isEmpty: false,
  84. goodsList: [],
  85. loadStatus: 'loadmore', //loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态
  86. lastPage: 1,
  87. currentPage: 1,
  88. // 瀑布流 350-330
  89. addTime: 100, //排序间隙时间
  90. leftHeight: 0,
  91. rightHeight: 0,
  92. leftList: [],
  93. rightList: [],
  94. tempList: []
  95. };
  96. },
  97. // 触底加载更多
  98. onReachBottom() {
  99. if (this.currentPage < this.lastPage) {
  100. this.currentPage += 1;
  101. this.getGoodsList();
  102. }
  103. },
  104. onLoad() {
  105. this.activityInfo = this.$Route.query;
  106. this.getGoodsList();
  107. this.getCartList();
  108. },
  109. mounted() {
  110. this.$nextTick(() => {
  111. this.getTime();
  112. });
  113. },
  114. methods: {
  115. ...mapActions(['getCartList']),
  116. // 瀑布流相关
  117. async splitData() {
  118. if (!this.tempList.length) return;
  119. let item = this.tempList[0];
  120. if (!item) return;
  121. // 分左右
  122. if (this.leftHeight < this.rightHeight) {
  123. this.leftHeight += item.activity_discounts_tags.length ? 350 : 330;
  124. this.leftList.push(item);
  125. } else if (this.leftHeight > this.rightHeight) {
  126. this.rightHeight += item.activity_discounts_tags.length ? 350 : 330;
  127. this.rightList.push(item);
  128. } else {
  129. this.leftHeight += item.activity_discounts_tags.length ? 350 : 330;
  130. this.leftList.push(item);
  131. }
  132. // 移除临时列表的第一项,如果临时数组还有数据,继续循环
  133. this.tempList.splice(0, 1);
  134. if (this.tempList.length) {
  135. setTimeout(() => {
  136. this.splitData();
  137. }, this.addTime);
  138. }
  139. },
  140. clear() {
  141. this.leftList = [];
  142. this.rightList = [];
  143. this.leftHeight = 0;
  144. this.rightHeight = 0;
  145. this.tempList = [];
  146. },
  147. // 计算倒计时
  148. getTime() {
  149. let nowTime = new Date().getTime();
  150. let { endtime, starttime } = this.activityInfo;
  151. endtime = endtime * 1000;
  152. starttime = starttime * 1000;
  153. // 当前时间小于开始时间,未开始
  154. if (nowTime < starttime) {
  155. this.timeRule.title = '距开始';
  156. this.timeRule.time = starttime - nowTime;
  157. }
  158. // 当前时间大于开始时间,小于结束时间,进行中
  159. if (nowTime > starttime && nowTime < endtime) {
  160. this.timeRule.title = '距结束';
  161. this.timeRule.time = endtime - nowTime;
  162. }
  163. // 当前时间大于结束时间,已结束
  164. if (nowTime > endtime) {
  165. this.timeRule.title = '已结束';
  166. this.timeRule.time = 0;
  167. }
  168. },
  169. // 商品列表
  170. getGoodsList() {
  171. let that = this;
  172. that.loadStatus = 'loading';
  173. that.$http('goods.lists', {
  174. goods_ids: that.activityInfo.goods_ids,
  175. page: that.currentPage
  176. }).then(res => {
  177. if (res.code === 1) {
  178. that.goodsList = [...that.goodsList, ...res.data.data];
  179. that.isEmpty = !that.goodsList.length;
  180. that.lastPage = res.data.last_page;
  181. that.loadStatus = that.currentPage < res.data.last_page ? 'loadmore' : 'nomore';
  182. that.tempList = res.data.data;
  183. that.splitData();
  184. }
  185. });
  186. }
  187. }
  188. };
  189. </script>
  190. <style lang="scss">
  191. @mixin vue-flex($direction: row) {
  192. /* #ifndef APP-NVUE */
  193. display: flex;
  194. flex-direction: $direction;
  195. /* #endif */
  196. }
  197. .u-waterfall {
  198. @include vue-flex;
  199. flex-direction: row;
  200. align-items: flex-start;
  201. }
  202. .u-column {
  203. @include vue-flex;
  204. flex: 1;
  205. flex-direction: column;
  206. height: auto;
  207. }
  208. .tip-list-box {
  209. background-color: #f6f6f6;
  210. padding: 20rpx;
  211. }
  212. .tip-list {
  213. font-size: 28rpx;
  214. background-color: #fff;
  215. border-radius: 20rpx;
  216. }
  217. </style>