tabs.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <template>
  2. <view
  3. class="tabs"
  4. >
  5. <scroll-view class="active-switch" scroll-x :scroll-into-view="id" scroll-with-animation>
  6. <view class="switch-container" >
  7. <view
  8. v-for="(item,index) in TabList" :key="index"
  9. :class="['active-item',currentTab==index&&'focus',TabList.length==3&&'fix']"
  10. @tap="tabChange(index)"
  11. :id='`tab_${index}`'
  12. >
  13. <view class="item">{{item.title}}</view>
  14. </view>
  15. <view class="focus-line"
  16. :class="[TabList.length==3&&'fix']"
  17. :style="{transform:transformX}"
  18. >
  19. </view>
  20. </view>
  21. </scroll-view>
  22. <view class="tab-pane-view"
  23. @touchstart='touchstart'
  24. @touchend='touchend'
  25. >
  26. <view
  27. class="tab-pane-group"
  28. :style="{transform:transformXx}"
  29. >
  30. <slot></slot>
  31. </view>
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. export default {
  37. name:'Tabs',
  38. data(){
  39. return {
  40. id:'tab_0',
  41. start:0
  42. }
  43. },
  44. props:{
  45. TabList:{
  46. default:()=>{
  47. return []
  48. },
  49. type:Array
  50. },
  51. currentTab:{
  52. default:0,
  53. type:Number
  54. }
  55. },
  56. computed:{
  57. transformX(){
  58. let currentTab = this.currentTab;
  59. return `translate3d(${currentTab*100}%, 0px, 0px)`
  60. },
  61. transformXx(){
  62. let currentTab = this.currentTab;
  63. return `translate3d(-${currentTab*100}%, 0px, 0px)`
  64. }
  65. },
  66. methods:{
  67. tabChange(index){
  68. if(this.currentTab!=index){
  69. console.log(`emit:${index}`);
  70. this.$emit('tabs',index);
  71. this.bus.$emit('tabs',index) //事件,这里触发tabs事件
  72. this.id = `tab_${index}`
  73. }
  74. },
  75. touchstart(e){
  76. this.start = e.touches[0].clientX;
  77. },
  78. touchend(e){
  79. let end = e.changedTouches[0].clientX;
  80. if(end-this.start>100&&this.currentTab>=1){
  81. this.tabChange(this.currentTab-1)
  82. }else if(this.start-end>100&&this.currentTab<this.TabList.length-1){
  83. this.tabChange(this.currentTab+1)
  84. }
  85. }
  86. }
  87. }
  88. </script>
  89. <style lang="stylus">
  90. .tabs
  91. position relative
  92. height 100vh
  93. display flex
  94. flex-direction column
  95. .active-switch
  96. overflow scroll
  97. .switch-container
  98. position relative
  99. display flex
  100. flex-direction row
  101. .focus-line
  102. flex 1
  103. width 160upx
  104. position absolute
  105. bottom 0
  106. border-bottom 4upx solid #f07
  107. transition 0.3s
  108. &.fix
  109. width 250upx
  110. .active-item
  111. position relative
  112. min-width 160upx
  113. width 160upx
  114. flex 1
  115. height 100upx
  116. transition .3s
  117. background-color: #fff
  118. color #000
  119. text-align: center
  120. display: flex
  121. flex-direction: column
  122. justify-content: space-around
  123. border-bottom 1upx solid rgba(0,0,0,0.5)
  124. &.focus
  125. background #fff
  126. color #f07
  127. transition-duration: .3s
  128. &.fix
  129. width 250upx
  130. .item
  131. // width: 220upx
  132. padding: 0 5upx
  133. overflow hidden
  134. font-size: 28upx
  135. .tab-pane-view
  136. overflow hidden
  137. background-color: #f7f7f7
  138. flex 1
  139. .tab-pane-group
  140. display: block;
  141. white-space: nowrap;
  142. -webkit-transition: all .3s;
  143. transition: all .3s;
  144. width: 100%;
  145. overflow: visible;
  146. will-change: transform,left,top;
  147. min-height 100upx
  148. height 100%
  149. .tab-pane-item
  150. width: 100%;
  151. min-height 100upx
  152. display: inline-block
  153. white-space: initial;
  154. vertical-align: top;
  155. font-size: 24upx;
  156. box-sizing: border-box;
  157. overflow: auto
  158. </style>