You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.4 KiB
160 lines
4.4 KiB
|
4 years ago
|
|
||
|
|
<template>
|
||
|
|
<view
|
||
|
|
class="tabs"
|
||
|
|
>
|
||
|
|
<scroll-view class="active-switch" scroll-x :scroll-into-view="id" scroll-with-animation>
|
||
|
|
<view class="switch-container" >
|
||
|
|
<view
|
||
|
|
v-for="(item,index) in TabList" :key="index"
|
||
|
|
:class="['active-item',currentTab==index&&'focus',TabList.length==3&&'fix']"
|
||
|
|
@tap="tabChange(index)"
|
||
|
|
:id='`tab_${index}`'
|
||
|
|
>
|
||
|
|
<view class="item">{{item.title}}</view>
|
||
|
|
</view>
|
||
|
|
<view class="focus-line"
|
||
|
|
:class="[TabList.length==3&&'fix']"
|
||
|
|
:style="{transform:transformX}"
|
||
|
|
>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
</scroll-view>
|
||
|
|
<view class="tab-pane-view"
|
||
|
|
@touchstart='touchstart'
|
||
|
|
@touchend='touchend'
|
||
|
|
>
|
||
|
|
<view
|
||
|
|
class="tab-pane-group"
|
||
|
|
:style="{transform:transformXx}"
|
||
|
|
>
|
||
|
|
<slot></slot>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
</view>
|
||
|
|
</template>
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
name:'Tabs',
|
||
|
|
data(){
|
||
|
|
return {
|
||
|
|
id:'tab_0',
|
||
|
|
start:0
|
||
|
|
}
|
||
|
|
},
|
||
|
|
props:{
|
||
|
|
TabList:{
|
||
|
|
default:()=>{
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
type:Array
|
||
|
|
},
|
||
|
|
currentTab:{
|
||
|
|
default:0,
|
||
|
|
type:Number
|
||
|
|
}
|
||
|
|
},
|
||
|
|
computed:{
|
||
|
|
transformX(){
|
||
|
|
let currentTab = this.currentTab;
|
||
|
|
return `translate3d(${currentTab*100}%, 0px, 0px)`
|
||
|
|
},
|
||
|
|
transformXx(){
|
||
|
|
let currentTab = this.currentTab;
|
||
|
|
return `translate3d(-${currentTab*100}%, 0px, 0px)`
|
||
|
|
}
|
||
|
|
},
|
||
|
|
methods:{
|
||
|
|
tabChange(index){
|
||
|
|
if(this.currentTab!=index){
|
||
|
|
console.log(`emit:${index}`);
|
||
|
|
this.$emit('tabs',index);
|
||
|
|
this.bus.$emit('tabs',index) //事件,这里触发tabs事件
|
||
|
|
this.id = `tab_${index}`
|
||
|
|
}
|
||
|
|
},
|
||
|
|
touchstart(e){
|
||
|
|
this.start = e.touches[0].clientX;
|
||
|
|
},
|
||
|
|
touchend(e){
|
||
|
|
let end = e.changedTouches[0].clientX;
|
||
|
|
if(end-this.start>100&&this.currentTab>=1){
|
||
|
|
this.tabChange(this.currentTab-1)
|
||
|
|
}else if(this.start-end>100&&this.currentTab<this.TabList.length-1){
|
||
|
|
this.tabChange(this.currentTab+1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<style lang="stylus">
|
||
|
|
.tabs
|
||
|
|
position relative
|
||
|
|
height 100vh
|
||
|
|
display flex
|
||
|
|
flex-direction column
|
||
|
|
.active-switch
|
||
|
|
overflow scroll
|
||
|
|
.switch-container
|
||
|
|
position relative
|
||
|
|
display flex
|
||
|
|
flex-direction row
|
||
|
|
.focus-line
|
||
|
|
flex 1
|
||
|
|
width 160upx
|
||
|
|
position absolute
|
||
|
|
bottom 0
|
||
|
|
border-bottom 4upx solid #f07
|
||
|
|
transition 0.3s
|
||
|
|
&.fix
|
||
|
|
width 250upx
|
||
|
|
.active-item
|
||
|
|
position relative
|
||
|
|
min-width 160upx
|
||
|
|
width 160upx
|
||
|
|
flex 1
|
||
|
|
height 100upx
|
||
|
|
transition .3s
|
||
|
|
background-color: #fff
|
||
|
|
color #000
|
||
|
|
text-align: center
|
||
|
|
display: flex
|
||
|
|
flex-direction: column
|
||
|
|
justify-content: space-around
|
||
|
|
border-bottom 1upx solid rgba(0,0,0,0.5)
|
||
|
|
&.focus
|
||
|
|
background #fff
|
||
|
|
color #f07
|
||
|
|
transition-duration: .3s
|
||
|
|
&.fix
|
||
|
|
width 250upx
|
||
|
|
.item
|
||
|
|
// width: 220upx
|
||
|
|
padding: 0 5upx
|
||
|
|
overflow hidden
|
||
|
|
font-size: 28upx
|
||
|
|
.tab-pane-view
|
||
|
|
overflow hidden
|
||
|
|
background-color: #f7f7f7
|
||
|
|
flex 1
|
||
|
|
.tab-pane-group
|
||
|
|
display: block;
|
||
|
|
white-space: nowrap;
|
||
|
|
-webkit-transition: all .3s;
|
||
|
|
transition: all .3s;
|
||
|
|
width: 100%;
|
||
|
|
overflow: visible;
|
||
|
|
will-change: transform,left,top;
|
||
|
|
min-height 100upx
|
||
|
|
height 100%
|
||
|
|
.tab-pane-item
|
||
|
|
width: 100%;
|
||
|
|
min-height 100upx
|
||
|
|
display: inline-block
|
||
|
|
white-space: initial;
|
||
|
|
vertical-align: top;
|
||
|
|
font-size: 24upx;
|
||
|
|
box-sizing: border-box;
|
||
|
|
overflow: auto
|
||
|
|
</style>
|