category.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <template>
  2. <view class="content">
  3. <scroll-view scroll-y class="left-aside">
  4. <view v-for="item in flist" :key="item.id" class="f-item b-b" :class="{active: item.id === currentId}" @click="tabtap(item)">
  5. {{item.name}}
  6. </view>
  7. </scroll-view>
  8. <scroll-view scroll-with-animation scroll-y class="right-aside" @scroll="asideScroll" :scroll-top="tabScrollTop">
  9. <view v-for="item in slist" :key="item.id" class="s-list" :id="'main-'+item.id">
  10. <text class="s-item">{{item.name}}</text>
  11. <view class="t-list">
  12. <view @click="navToList(item.id, titem.id)" v-if="titem.pid === item.id" class="t-item" v-for="titem in tlist" :key="titem.id">
  13. <image :src="titem.picture"></image>
  14. <text>{{titem.name}}</text>
  15. </view>
  16. </view>
  17. </view>
  18. </scroll-view>
  19. </view>
  20. </template>
  21. <script>
  22. export default {
  23. data() {
  24. return {
  25. sizeCalcState: false,
  26. tabScrollTop: 0,
  27. currentId: 1,
  28. flist: [],
  29. slist: [],
  30. tlist: [],
  31. }
  32. },
  33. onLoad(){
  34. this.loadData();
  35. },
  36. methods: {
  37. async loadData(){
  38. let list = await this.$util.json('cateList');
  39. list.forEach(item=>{
  40. // console.log('item---->',item)
  41. if(!item.pid){
  42. this.flist.push(item); //pid为父级id, 没有pid或者pid=0是一级分类
  43. // console.log('flist---->',this.flist)
  44. }else if(!item.picture){
  45. this.slist.push(item); //没有图的是2级分类
  46. // console.log('slist---->',this.slist)
  47. }else{
  48. this.tlist.push(item); //3级分类
  49. // console.log('tlist---->',this.tlist)
  50. }
  51. })
  52. },
  53. //一级分类点击
  54. tabtap(item){
  55. if(!this.sizeCalcState){
  56. this.calcSize();
  57. }
  58. this.currentId = item.id;
  59. // console.log('this.currentId',this.currentId)
  60. // console.log('this.id',item.id)
  61. // console.log('this.slist',this.slist)
  62. let index = this.slist.findIndex(sitem=>sitem.pid === item.id);
  63. this.tabScrollTop = this.slist[index].top;
  64. },
  65. //右侧栏滚动
  66. asideScroll(e){
  67. if(!this.sizeCalcState){
  68. this.calcSize();
  69. }
  70. let scrollTop = e.detail.scrollTop;
  71. let tabs = this.slist.filter(item=>item.top <= scrollTop).reverse();
  72. if(tabs.length > 0){
  73. this.currentId = tabs[0].pid;
  74. }
  75. },
  76. //计算右侧栏每个tab的高度等信息
  77. calcSize(){
  78. let h = 0;
  79. this.slist.forEach(item=>{
  80. let view = uni.createSelectorQuery().select("#main-" + item.id);
  81. view.fields({
  82. size: true
  83. }, data => {
  84. item.top = h;
  85. h += data.height;
  86. item.bottom = h;
  87. }).exec();
  88. })
  89. this.sizeCalcState = true;
  90. },
  91. navToList(sid, tid){
  92. uni.navigateTo({
  93. url: `/pages/product/list?fid=${this.currentId}&sid=${sid}&tid=${tid}`
  94. })
  95. }
  96. }
  97. }
  98. </script>
  99. <style lang='scss'>
  100. page,
  101. .content {
  102. height: 100%;
  103. background-color: #f8f8f8;
  104. }
  105. .content {
  106. display: flex;
  107. }
  108. .left-aside {
  109. flex-shrink: 0;
  110. width: 200rpx;
  111. height: 100%;
  112. background-color: #fff;
  113. }
  114. .f-item {
  115. display: flex;
  116. align-items: center;
  117. justify-content: center;
  118. width: 100%;
  119. height: 100rpx;
  120. font-size: 28rpx;
  121. color: #333333;
  122. position: relative;
  123. &.active{
  124. color:$color-system;
  125. background: #f8f8f8;
  126. &:before{
  127. content: '';
  128. position: absolute;
  129. left: 0;
  130. top: 50%;
  131. transform: translateY(-50%);
  132. height: 60rpx;
  133. width: 8rpx;
  134. background-color: $color-system;
  135. border-radius: 0 4px 4px 0;
  136. opacity: .8;
  137. }
  138. }
  139. }
  140. .right-aside{
  141. flex: 1;
  142. overflow: hidden;
  143. padding-left: 20rpx;
  144. }
  145. .s-item{
  146. display: flex;
  147. align-items: center;
  148. height: 70rpx;
  149. padding-top: 8rpx;
  150. font-size: 28rpx;
  151. color: $text-color;
  152. }
  153. .t-list{
  154. display: flex;
  155. flex-wrap: wrap;
  156. width: 100%;
  157. background: #fff;
  158. padding-top: 12rpx;
  159. &:after{
  160. content: '';
  161. flex: 99;
  162. height: 0;
  163. }
  164. }
  165. .t-item{
  166. flex-shrink: 0;
  167. display: flex;
  168. justify-content: center;
  169. align-items: center;
  170. flex-direction: column;
  171. width: 176rpx;
  172. font-size: 26rpx;
  173. color: #666;
  174. padding-bottom: 20rpx;
  175. image{
  176. width: 140rpx;
  177. height: 140rpx;
  178. }
  179. }
  180. </style>