时空网前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
7.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <template>
  2. <view class="lf-row-center lf-flex-column">
  3. <block v-if="tab_list.length">
  4. <view class="ctab">
  5. <u-tabs :list="tab_list" :is-scroll="true" :show-bar="false" :current="current" @change="change"></u-tabs>
  6. </view>
  7. <swiper :style="{height: 'calc('+ windowHeight +'px - 110rpx)', width: '750rpx'}" :current="current" @change="swiperChange">
  8. <swiper-item v-for="(tab, tabIndex) in tab_list" :key="tabIndex">
  9. <scroll-view class="com" :scroll-y="true" :refresher-enabled="true" :refresher-triggered="isRefresher" @scrolltolower="onScrolltolower" @refresherrefresh="onRefresherrefresh">
  10. <view class="lf-row-between list" v-for="(item, index) in tab.list" :key="item.id" @click="toDetail(item)">
  11. <view class="left">
  12. <image :src="item.cover" mode="aspectFill"></image>
  13. </view>
  14. <view class="right">
  15. <view class="lf-line-2 title">{{ item.name }}</view>
  16. <view class="lf-flex tips">
  17. <view class="lf-row-between lf-flex-1" v-if="item.specs[0]">
  18. <view class="lf-flex">
  19. <view class="u-line-progress">
  20. <u-line-progress :percent="item.specs[0].sold_percent" height="20" :striped="true" active-color="#FE9903" :show-percent="false" inactive-color="#F5F5F5"></u-line-progress>
  21. </view>
  22. <text class="progress lf-m-r-10">{{ item.specs[0].sold_percent_text }}</text>
  23. </view>
  24. <view>
  25. <text class="bought">{{ item.specs[0].sold_stock_text }}</text>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="lf-row-between price">
  30. <lf-price :price="item.specs[0].selling_price" v-if="item.specs[0]"></lf-price>
  31. <text class="lf-font-24 original-price" v-if="item.specs[0]">{{ item.specs[0].original_price }}</text>
  32. <text v-else></text>
  33. <button>立即抢购</button>
  34. </view>
  35. </view>
  36. </view>
  37. <!-- 空数据的情况 -->
  38. <view class="loading-more">
  39. <text v-if="tab.list.length" :class="{'loading-more-text': tab.loadingClass}">{{ tab.loadingText }}</text>
  40. <my-nocontent v-else></my-nocontent>
  41. </view>
  42. <!-- 回到顶部 -->
  43. <u-back-top :scroll-top="pageScrollTop" :custom-style="{background: 'rgba(51, 51 51, 0.3)'}"></u-back-top>
  44. </scroll-view>
  45. </swiper-item>
  46. </swiper>
  47. </block>
  48. <block v-else>
  49. <my-nocontent></my-nocontent>
  50. </block>
  51. </view>
  52. </template>
  53. <script>
  54. export default {
  55. data() {
  56. return {
  57. tab_list: [],
  58. current: 0, // tab下表
  59. pageSize: 10,
  60. shareInfo: {},
  61. windowHeight: 0, // 屏幕可用高度
  62. isRefresher: false // scroll-view下拉刷新状态,当前默认没有触发
  63. }
  64. },
  65. onLoad() {
  66. this.windowHeight = getApp().globalData.windowHeight;
  67. this.getCategoryList();
  68. this.getShareInfo();
  69. },
  70. methods: {
  71. // 获取分享信息
  72. getShareInfo(){
  73. this.$http(this.API.API_SHARE_HOME).then(res => {
  74. this.shareInfo = res.data;
  75. });
  76. },
  77. // 切换tab
  78. change(index) {
  79. this.current = index;
  80. if(this.tab_list[index].list.length <= 0){
  81. this.getGoodsList(); // tab下没有数据,请求第一页
  82. }
  83. },
  84. // 滑块下标值变化
  85. swiperChange(event){
  86. this.current = event.detail.current;
  87. if(event.detail.source == '') return; // 如果是被动出发,没有事件类型则不做处理
  88. if(this.tab_list[event.detail.current].list.length <= 0){
  89. this.getGoodsList(); // tab下没有数据,请求第一页
  90. }
  91. },
  92. // 获取分类tab
  93. getCategoryList(options = {}){
  94. this.$http(this.API.API_CATEGORY_LIST).then(res => {
  95. let res_list = res.data || [];
  96. let tab_list = res_list.map(item => {
  97. return {
  98. id: item.id,
  99. name: item.name,
  100. type: item.type,
  101. list: [],
  102. loadingClass: true,
  103. loadingText: '正在加载中',
  104. page: 1,
  105. isPage: true
  106. }
  107. });
  108. if(options.type == 'pageRefresh'){
  109. uni.stopPullDownRefresh();
  110. }else if(options.type == 'scrollRefresh'){
  111. this.isRefresher = false;
  112. }
  113. this.tab_list = tab_list;
  114. this.getGoodsList();
  115. })
  116. },
  117. // 获取分类下的商品列表
  118. getGoodsList(){
  119. let per_page = this.pageSize;
  120. let tab_item = this.tab_list[this.current];
  121. this.$http(this.API.API_GOODS_LIST, {
  122. category_id: tab_item.id,
  123. type: tab_item.type,
  124. page: tab_item.page,
  125. per_page
  126. }).then(res => {
  127. let isPage = res.data.has_more_page;
  128. tab_item.isPage = isPage;
  129. if(!isPage){
  130. tab_item.loadingClass = false;
  131. tab_item.loadingText = '没有更多数据啦~';
  132. }
  133. if(tab_item.page == 1){
  134. tab_item.list = res.data.items;
  135. }else{
  136. tab_item.list.push(...res.data.items);
  137. }
  138. })
  139. },
  140. // 去到详情页
  141. toDetail(item){
  142. this.$url('/pages/goodsDetail/index?id='+ item.id);
  143. },
  144. // 页面触底,加载下一页
  145. onScrolltolower(){
  146. let tab_item = this.tab_list[this.current];
  147. if(tab_item.isPage){
  148. tab_item.page = tab_item.page + 1;
  149. this.getGoodsList();
  150. }
  151. },
  152. // scroll-view 下拉刷新
  153. onRefresherrefresh(){
  154. this.isRefresher = true;
  155. this.getCategoryList({type: 'scrollRefresh'});
  156. }
  157. },
  158. // page 下拉刷新
  159. onPullDownRefresh(){
  160. // 新版逻辑,刷新则整个数据全部重新获取
  161. this.getCategoryList({type: 'pageRefresh'});
  162. // 旧版逻辑,刷新只刷tab下的商品列表
  163. // let tab_item = this.tab_list[this.current];
  164. // tab_item.page = 1;
  165. // tab_item.isPage = true;
  166. // tab_item.loadingClass = true;
  167. // tab_item.loadingText = '正在加载中';
  168. // this.getGoodsList();
  169. },
  170. onShareAppMessage(){
  171. let shareInfo = {
  172. title: this.shareInfo.title || '欢迎使用时空网小程序',
  173. path: '/pages/route/index?route=home'
  174. }
  175. if(this.shareInfo.cover){
  176. shareInfo.imageUrl = this.shareInfo.cover;
  177. }
  178. return shareInfo;
  179. }
  180. }
  181. </script>
  182. <style lang="scss" scoped>
  183. .title {
  184. font-size: 28rpx;
  185. color: $u-content-color;
  186. height: 88rpx;
  187. }
  188. // tab
  189. .ctab{
  190. width: 100%;
  191. margin: 20rpx 0 0rpx 0rpx;
  192. padding: 0 22rpx;
  193. }
  194. // 商品列表
  195. .com{
  196. width: 100%;
  197. height: 100%;
  198. overflow: hidden;
  199. .list{
  200. border-radius: 10rpx;
  201. overflow: hidden;
  202. margin: 20rpx 32rpx;
  203. background-color: #FFFFFF;
  204. box-shadow: 0 10rpx 20rpx 0 rgba(0, 0, 0, 0.1);
  205. align-items: flex-start;
  206. .left{
  207. overflow: hidden;
  208. image{
  209. width: 204rpx;
  210. height: 204rpx;
  211. margin: 20rpx;
  212. border-radius: 10rpx;
  213. }
  214. }
  215. .right{
  216. overflow: hidden;
  217. width: 64%;
  218. .title{
  219. margin: 18rpx 20rpx 0 0;
  220. color: #222222;
  221. font-size: 32rpx;
  222. }
  223. .tips{
  224. margin: 16rpx 0;
  225. overflow: hidden;
  226. .u-line-progress{
  227. width: 112rpx;
  228. overflow: hidden;
  229. margin-right:20rpx ;
  230. }
  231. .progress{
  232. color: #777777;
  233. font-size: 24rpx;
  234. }
  235. .bought{
  236. color: #777777;
  237. font-size: 24rpx;
  238. margin-right: 20rpx;
  239. }
  240. }
  241. .price{
  242. overflow: hidden;
  243. color:#FF0000;
  244. .original-price{
  245. text-decoration: line-through;
  246. color: #777777;
  247. }
  248. // text{
  249. // font-size: 48rpx;
  250. // color:#FF0000;
  251. // font-weight: 500;
  252. // }
  253. // text:nth-child(1){
  254. // color: #FF0000;
  255. // font-size: 28rpx;
  256. // }
  257. // text:nth-child(2){
  258. // color: #FF0000;
  259. // font-size: 48rpx;
  260. // }
  261. // text:nth-child(3){
  262. // color: #FF0000;
  263. // font-size: 28rpx;
  264. // }
  265. // text:nth-child(4){
  266. // color: #777777;
  267. // font-size: 28rpx;
  268. // text-decoration:line-through;
  269. // font-weight: 400;
  270. // }
  271. button{
  272. width: 160rpx;
  273. height: 60rpx;
  274. background: #FE9903;
  275. border-radius: 50px;
  276. font-size: 24rpx;
  277. color: #FFFFFF;
  278. margin: 0rpx 20rpx 0rpx 20rpx;
  279. border: none;
  280. }
  281. }
  282. }
  283. }
  284. }
  285. </style>