goods-coupon-list.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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.productName"></cm-simple-search>
  7. </view>
  8. <!-- 商品列表 -->
  9. <view class="product-list">
  10. <view class="product-item" v-for="(product, index) in productList" :key="product.productId">
  11. <cm-product :data="product"></cm-product>
  12. </view>
  13. </view>
  14. <!-- 加载更多 -->
  15. <cm-loadmore :hasNextPage="hasNextPage" :isLoading="isLoading" :visiable="!hideLoadmore"></cm-loadmore>
  16. <!-- 安全区域 -->
  17. <cm-safe-area-bottom v-if="hideLoadmore"></cm-safe-area-bottom>
  18. <!-- 购物车 -->
  19. <cm-drag :cartNum="kindCount" @btnClick="toCart"></cm-drag>
  20. </view>
  21. </template>
  22. <script>
  23. import { fetchProductByCoupon } from '@/services/api/coupon.js'
  24. import { debounce } from '@/common/utils.js'
  25. import { mapGetters } from 'vuex'
  26. import { makeQuery } from '@/pages/views/goods/config/config.js'
  27. export default {
  28. data() {
  29. return {
  30. isRequest: true,
  31. listQuery: {
  32. productName: '',
  33. userId: '',
  34. couponId: '',
  35. pageNum: 1,
  36. pageSize: 12
  37. },
  38. navInfo: {},
  39. productList: [],
  40. hasNextPage: true,
  41. total: 0,
  42. isLoading: false
  43. }
  44. },
  45. computed: {
  46. ...mapGetters(['userId', 'kindCount']),
  47. hideLoadmore() {
  48. return this.isRequest || this.productList.length <= this.listQuery.pageSize
  49. }
  50. },
  51. onReachBottom() {
  52. this.loadMore()
  53. },
  54. onLoad(options) {
  55. this.initQueryList(options)
  56. },
  57. methods: {
  58. // 跳转到购物车
  59. toCart() {
  60. this.$router.redirectTo('cart/cart')
  61. },
  62. // 搜索商品
  63. onSearch() {
  64. this.filterProductList()
  65. },
  66. // 取消搜索
  67. onCancel() {
  68. this.listQuery.name = ''
  69. this.filterProductList()
  70. },
  71. // 筛选商品
  72. onFilter(e) {
  73. const { current, sort } = e
  74. if (current === 0) {
  75. // 综合排序
  76. this.listQuery.sortType = 1
  77. } else if (current === 1) {
  78. // 价格高低
  79. this.listQuery.sortType = sort === 'desc' ? 3 : 2
  80. } else {
  81. // 最新上架
  82. this.listQuery.sortType = 4
  83. }
  84. this.filterProductList()
  85. },
  86. // 初始化查询参数
  87. initQueryList(options) {
  88. this.listQuery.userId = this.userId
  89. this.listQuery.couponId = options.couponId
  90. this.fetchProductList()
  91. },
  92. // 加载更多
  93. loadMore() {
  94. if (!this.hasNextPage) return
  95. this.isLoading = true
  96. this.fetchProductList()
  97. },
  98. // 搜索商品
  99. filterProductList() {
  100. this.productList = []
  101. this.listQuery.pageNum = 1
  102. this.fetchProductList()
  103. },
  104. // 获取商品列表
  105. fetchProductList: debounce(async function() {
  106. try {
  107. const resultProductData = await fetchProductByCoupon(this.listQuery)
  108. this.productList = [...this.productList, ...resultProductData.data.list]
  109. this.hasNextPage = resultProductData.data.hasNextPage
  110. this.total = resultProductData.data.total
  111. this.listQuery.pageNum++
  112. this.isRequest = false
  113. this.isLoading = false
  114. } catch (e) {
  115. console.log(e)
  116. console.log('获取商品列表失败')
  117. }
  118. }, 200)
  119. }
  120. }
  121. </script>
  122. <style lang="scss" scoped>
  123. .goods-list {
  124. box-sizing: border-box;
  125. min-height: 100vh;
  126. .product-list {
  127. display: grid;
  128. grid-template-columns: repeat(3, 1fr);
  129. grid-row-gap: 16rpx;
  130. grid-column-gap: 16rpx;
  131. padding: 16rpx 24rpx;
  132. }
  133. }
  134. </style>