Category.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <template>
  2. <div class="categray">
  3. <div>
  4. <header class="category-header wrap van-hairline--bottom">
  5. <i class="nbicon nbfanhui" @click="goHome"></i>
  6. <div class="header-search">
  7. <i class="nbicon nbSearch"></i>
  8. <router-link tag="span" class="search-title" to="./product-list?from=category">全场50元起步</router-link>
  9. </div>
  10. <i class="iconfont icon-More"></i>
  11. </header>
  12. <nav-bar></nav-bar>
  13. <div class="search-wrap" ref="searchWrap">
  14. <list-scroll :scroll-data="categoryData" class="nav-side-wrapper">
  15. <ul class="nav-side">
  16. <li
  17. v-for="item in categoryData"
  18. :key="item.categoryId"
  19. v-text="item.categoryName"
  20. :class="{'active' : currentIndex == item.categoryId}"
  21. @click="selectMenu(item.categoryId)"
  22. ></li>
  23. </ul>
  24. </list-scroll>
  25. <div class="search-content">
  26. <list-scroll :scroll-data="categoryData" >
  27. <div class="swiper-container">
  28. <div class="swiper-wrapper">
  29. <template v-for="(category, index) in categoryData">
  30. <div class="swiper-slide" v-if="currentIndex == category.categoryId" :key="index">
  31. <!-- <img class="category-main-img" :src="category.mainImgUrl" v-if="category.mainImgUrl"/> -->
  32. <div class="category-list" v-for="(products, index) in category.secondLevelCategoryVOS" :key="index">
  33. <p class="catogory-title">{{products.categoryName}}</p>
  34. <div class="product-item" v-for="(product, index) in products.thirdLevelCategoryVOS" :key="index" @click="selectProduct(product)">
  35. <img src="//s.weituibao.com/1583591077131/%E5%88%86%E7%B1%BB.png" class="product-img"/>
  36. <p v-text="product.categoryName" class="product-title"></p>
  37. </div>
  38. </div>
  39. </div>
  40. </template>
  41. </div>
  42. </div>
  43. </list-scroll>
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. import { reactive, onMounted, ref, toRefs } from 'vue'
  51. import { useRouter } from 'vue-router'
  52. import navBar from '@/components/NavBar'
  53. import listScroll from '@/components/ListScroll'
  54. import { getCategory } from "@/service/good";
  55. import { Toast } from 'vant'
  56. export default {
  57. components: {
  58. navBar,
  59. listScroll
  60. },
  61. setup() {
  62. const router = useRouter()
  63. // composition API 获取 refs 的形式
  64. const searchWrap = ref(null)
  65. const state = reactive({
  66. categoryData: [],
  67. currentIndex: 15
  68. })
  69. onMounted(async () => {
  70. let $screenHeight = document.documentElement.clientHeight
  71. console.log('searchWrap.value', searchWrap.value)
  72. searchWrap.value.style.height = $screenHeight - 100 + 'px'
  73. Toast.loading('加载中...')
  74. const { data } = await getCategory()
  75. Toast.clear()
  76. state.categoryData = data
  77. })
  78. const goHome = () => {
  79. router.push({ path: 'home' })
  80. }
  81. const selectMenu = (index) => {
  82. state.currentIndex = index
  83. }
  84. const selectProduct = (item) => {
  85. console.log('item', item.categoryId)
  86. router.push({ path: '/product-list', query: { categoryId: item.categoryId } })
  87. }
  88. return {
  89. ...toRefs(state),
  90. goHome,
  91. selectMenu,
  92. selectProduct,
  93. searchWrap
  94. }
  95. }
  96. }
  97. </script>
  98. <style lang="less" scoped>
  99. @import '../common/style/mixin';
  100. .categray {
  101. .category-header {
  102. background: #fff;
  103. position: fixed;
  104. left: 0;
  105. top: 0;
  106. .fj();
  107. .wh(100%, 50px);
  108. line-height: 50px;
  109. padding: 0 15px;
  110. box-sizing: border-box;
  111. font-size: 15px;
  112. color: #656771;
  113. z-index: 10000;
  114. &.active {
  115. background: @primary;
  116. }
  117. .icon-left {
  118. font-size: 25px;
  119. font-weight: bold;
  120. }
  121. .header-search {
  122. display: flex;
  123. width: 80%;
  124. height: 20px;
  125. line-height: 20px;
  126. margin: 10px 0;
  127. padding: 5px 0;
  128. color: #232326;
  129. background: #F7F7F7;
  130. border-radius: 20px;
  131. .nbSearch {
  132. padding: 0 10px 0 20px;
  133. font-size: 17px;
  134. }
  135. .search-title {
  136. font-size: 12px;
  137. color: #666;
  138. line-height: 21px;
  139. }
  140. }
  141. .icon-More {
  142. font-size: 20px;
  143. }
  144. }
  145. }
  146. .search-wrap {
  147. .fj();
  148. width: 100%;
  149. margin-top: 50px;
  150. background: #F8F8F8;
  151. .nav-side-wrapper {
  152. width: 28%;
  153. height: 100%;
  154. overflow: hidden;
  155. .nav-side {
  156. width: 100%;
  157. .boxSizing();
  158. background: #F8F8F8;
  159. li {
  160. width: 100%;
  161. height: 56px;
  162. text-align: center;
  163. line-height: 56px;
  164. font-size: 14px;
  165. &.active {
  166. color: @primary;
  167. background: #fff;
  168. }
  169. }
  170. }
  171. }
  172. .search-content {
  173. width: 72%;
  174. height: 100%;
  175. padding: 0 10px;
  176. background: #fff;
  177. overflow-y: scroll;
  178. touch-action: pan-y;
  179. * {
  180. touch-action: pan-y;
  181. }
  182. .boxSizing();
  183. .swiper-container {
  184. width: 100%;
  185. .swiper-slide {
  186. width: 100%;
  187. .category-main-img {
  188. width: 100%;
  189. }
  190. .category-list {
  191. display: flex;
  192. flex-wrap: wrap;
  193. flex-shrink: 0;
  194. width: 100%;
  195. .catogory-title {
  196. width: 100%;
  197. font-size: 17px;
  198. font-weight: 500;
  199. padding: 20px 0;
  200. }
  201. .product-item {
  202. width: 33.3333%;
  203. margin-bottom: 10px;
  204. text-align: center;
  205. font-size: 15px;
  206. .product-img {
  207. .wh(30px, 30px);
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. }
  215. .fade-out-enter-active, .fade-out-leave-active {
  216. // transition: opacity 0.5s;
  217. }
  218. .fade-out-enter, .fade-out-leave-to {
  219. // opacity: 0;
  220. }
  221. </style>