category.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <view class="category">
  3. <tui-skeleton v-if="isRequest" :loadingType="3" :isLoading="true"></tui-skeleton>
  4. <template v-else>
  5. <!-- 侧边导航 -->
  6. <scroll-view class="slide-navbar" :scroll-y="true">
  7. <template v-for="(item, index) in categories">
  8. <view
  9. class="slide"
  10. :class="{ active: index === current }"
  11. :key="item.id"
  12. v-text="item.name"
  13. @click="onClick(item, index)"
  14. ></view>
  15. </template>
  16. </scroll-view>
  17. <!-- 右侧容器 -->
  18. <scroll-view
  19. class="panel"
  20. :scroll-y="true"
  21. :scroll-with-animation="true"
  22. :scroll-top="scrollTop"
  23. @scroll="onScroll"
  24. >
  25. <view class="cate" v-for="(item, index) in smallTypeList" :key="index" @click="toGoodsFloor(item)">
  26. <image class="cate-icon" :src="item.crmIcon"></image>
  27. <view class="cate-name" v-text="item.name"></view>
  28. </view>
  29. </scroll-view>
  30. </template>
  31. </view>
  32. </template>
  33. <script>
  34. import { fetchProductTypeFirst, fetchProductTypeSecond } from '@/services/api/goods.js'
  35. export default {
  36. data() {
  37. return {
  38. isRequest: true,
  39. categories: [],
  40. current: 0,
  41. oldScrollTop: 0,
  42. scrollTop: 100
  43. }
  44. },
  45. computed: {
  46. smallTypeList() {
  47. const current = this.categories[this.current]
  48. return (current && current.smallTypeList) || []
  49. }
  50. },
  51. onShow() {
  52. this.fetchProductTypeFirst()
  53. },
  54. methods: {
  55. onClick(item, index) {
  56. this.current = index
  57. this.scrollTop = this.oldScrollTop
  58. this.$nextTick(() => {
  59. this.scrollTop = 0
  60. })
  61. },
  62. onScroll(e) {
  63. this.oldScrollTop = e.detail.scrollTop
  64. },
  65. // 获取一级商品分了列表
  66. async fetchProductTypeFirst() {
  67. try {
  68. const { data } = await fetchProductTypeFirst()
  69. this.categories = data
  70. this.isRequest = false
  71. } catch (e) {
  72. console.log(e)
  73. }
  74. },
  75. // 商品楼层
  76. toGoodsFloor(item) {
  77. this.$setStorage('NAVBAR', {
  78. type: 'second',
  79. id: item.smallTypeId,
  80. title: item.name
  81. })
  82. this.$router.navigateTo('goods/goods-list')
  83. }
  84. }
  85. }
  86. </script>
  87. <style lang="scss" scoped>
  88. .category {
  89. @extend .cm-flex-between;
  90. align-items: flex-start;
  91. background-color: #fff;
  92. .slide-navbar {
  93. width: 200rpx;
  94. height: 100vh;
  95. background-color: #f7f7f7;
  96. box-sizing: border-box;
  97. .slide {
  98. width: 100%;
  99. height: 94rpx;
  100. text-align: center;
  101. line-height: 94rpx;
  102. font-size: 28rpx;
  103. color: #666666;
  104. background-color: #f7f7f7;
  105. &.active {
  106. background-color: #fff;
  107. color: #ff457b;
  108. }
  109. }
  110. }
  111. .panel {
  112. width: 550rpx;
  113. height: 100vh;
  114. padding-bottom: 40rpx;
  115. background-color: #fff;
  116. box-sizing: border-box;
  117. &::after {
  118. content: '';
  119. display: block;
  120. clear: both;
  121. }
  122. .cate {
  123. float: left;
  124. margin-top: 40rpx;
  125. margin-left: 40rpx;
  126. @extend .cm-flex-center;
  127. flex-direction: column;
  128. .cate-icon {
  129. display: block;
  130. width: 128rpx;
  131. height: 128rpx;
  132. }
  133. .cate-name {
  134. @include ellipsis(1);
  135. width: 100%;
  136. margin-top: 16rpx;
  137. color: #666;
  138. font-size: 26rpx;
  139. text-align: center;
  140. }
  141. }
  142. }
  143. }
  144. </style>