goods-list.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <view class="goods-list">
  3. <tui-skeleton v-if="isRequest" :loadingType="3" :isLoading="true"></tui-skeleton>
  4. <view class="sticky-top">
  5. <!-- 搜索框 -->
  6. <cm-simple-search @search="onSearch" @cancel="onCancel" v-model="listQuery.name"></cm-simple-search>
  7. <!-- 筛选 -->
  8. <goods-filter @filter="onFilter"></goods-filter>
  9. </view>
  10. <!-- 商品列表 -->
  11. <view class="product-list">
  12. <view class="product-item" v-for="(product, index) in productList" :key="index">
  13. <cm-product :data="product"></cm-product>
  14. </view>
  15. </view>
  16. <!-- 商品列表为空 -->
  17. <template v-if="productList.length <= 0 && !isLoading">
  18. <tui-no-data :imgUrl="staticUrl + 'icon-empty-address.png'" :imgHeight="230" :imgWidth="290">
  19. <view class="empty-tip">暂无商品~~</view>
  20. </tui-no-data>
  21. </template>
  22. <!-- 加载更多 -->
  23. <cm-loadmore :hasNextPage="hasNextPage" :isLoading="isLoading" :visiable="!hideLoadmore"></cm-loadmore>
  24. <!-- 回到顶部 -->
  25. <tui-scroll-top :scrollTop="scrollTop" :bottom="60"></tui-scroll-top>
  26. <!-- 安全区域 -->
  27. <cm-safe-area-bottom v-if="hideLoadmore"></cm-safe-area-bottom>
  28. </view>
  29. </template>
  30. <script>
  31. import { fetchProductList } from '@/services/api/goods.js'
  32. import { debounce } from '@/common/utils.js'
  33. import { mapGetters } from 'vuex'
  34. import { makeQuery } from '@/pages/views/goods/config/config.js'
  35. export default {
  36. data() {
  37. return {
  38. isRequest: true,
  39. scrollTop: 0,
  40. listQuery: makeQuery(),
  41. navInfo: {},
  42. productList: [],
  43. hasNextPage: true,
  44. total: 0,
  45. isLoading: false
  46. }
  47. },
  48. computed: {
  49. ...mapGetters(['userId']),
  50. hideLoadmore() {
  51. return this.isRequest || this.productList.length <= this.listQuery.pageSize
  52. }
  53. },
  54. onPageScroll(e) {
  55. this.scrollTop = e.scrollTop
  56. },
  57. onReachBottom() {
  58. this.loadMore()
  59. },
  60. onLoad() {
  61. this.initQueryList()
  62. },
  63. methods: {
  64. // 搜索商品
  65. onSearch() {
  66. this.filterProductList()
  67. },
  68. // 取消搜索
  69. onCancel() {
  70. this.listQuery.name = ''
  71. this.filterProductList()
  72. },
  73. // 筛选商品
  74. onFilter(e) {
  75. const { current, sort } = e
  76. if (current === 0) {
  77. // 综合排序
  78. this.listQuery.sortType = 1
  79. } else if (current === 1) {
  80. // 价格高低
  81. this.listQuery.sortType = sort === 'desc' ? 3 : 2
  82. } else {
  83. // 最新上架
  84. this.listQuery.sortType = 4
  85. }
  86. this.filterProductList()
  87. },
  88. // 初始化查询参数
  89. initQueryList() {
  90. this.listQuery.userId = this.userId
  91. this.navInfo = this.$getStorage('NAVBAR')
  92. if (this.navInfo.title) {
  93. uni.setNavigationBarTitle({ title: this.navInfo.title })
  94. }
  95. if (this.navInfo.type === 'navbar') {
  96. // 从金刚区菜单进入
  97. this.listQuery.homeTypeId = this.navInfo.id
  98. this.listQuery.listType = 2
  99. } else if (this.navInfo.type === 'floor') {
  100. // 从楼层进入
  101. this.listQuery.homeFloorId = this.navInfo.id
  102. this.listQuery.listType = 3
  103. } else if (this.navInfo.type === 'second') {
  104. // 从二级菜单进入
  105. this.listQuery.smallTypeId = this.navInfo.id
  106. this.listQuery.listType = 4
  107. }
  108. this.fetchProductList()
  109. },
  110. // 加载更多
  111. loadMore() {
  112. if (!this.hasNextPage) return
  113. this.isLoading = true
  114. this.fetchProductList()
  115. },
  116. // 搜索商品
  117. filterProductList() {
  118. this.productList = []
  119. this.listQuery.pageNum = 1
  120. this.fetchProductList()
  121. },
  122. // 获取商品列表
  123. fetchProductList: debounce(async function() {
  124. try {
  125. if (this.listQuery.sortType === 1) {
  126. this.listQuery.productIds = this.productList.map(item => item.productId).join(',')
  127. } else {
  128. this.listQuery.productIds = ''
  129. }
  130. const { data } = await fetchProductList(this.listQuery)
  131. this.productList = [...this.productList, ...data.pageInfo.results]
  132. this.hasNextPage = data.pageInfo.hasNextPage
  133. this.total = data.pageInfo.totalRecord
  134. this.listQuery.pageNum++
  135. this.isRequest = false
  136. this.isLoading = false
  137. } catch (e) {
  138. console.log('获取商品列表失败')
  139. }
  140. }, 200)
  141. }
  142. }
  143. </script>
  144. <style lang="scss" scoped>
  145. .goods-list {
  146. box-sizing: border-box;
  147. min-height: 100vh;
  148. .product-list {
  149. display: grid;
  150. grid-template-columns: repeat(3, 1fr);
  151. grid-row-gap: 16rpx;
  152. grid-column-gap: 16rpx;
  153. padding: 16rpx 24rpx;
  154. }
  155. }
  156. </style>