category.vue 4.0 KB

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