可以点击切换tab也可以滑动切换tab
1.定义一个tabbar.vue,代码如下
<template>
<view class="tabs">
<view style="position:fixed;z-index:20;">
<scroll-view id="tab-bar" class="scroll-h" :scroll-x="true" :show-scrollbar="false" :scroll-into-view="scrollInto">
<view style="" :class="{'tabCenter':tabBars.length<4}">
<view v-for="(tab,index) in tabBars" :key="tab.id" class="uni-tab-item" :id="tab.id"
:data-current="index" @click="ontabtap">
<text class="uni-tab-item-title"
:class="tabIndex==index ? 'uni-tab-item-title-active' : ''">{{tab.name}}<text v-if="tab.count">({{tab.count}})</text></text>
<view class="uni-tab-item-line" v-if="tabIndex==index"></view>
</view>
</view>
</scroll-view>
<slot name="center"></slot>
</view>
<swiper :current="tabIndex" class="swiper-box" style="flex: 1;min-height:calc(100vh - 200rpx - 142rpx);margin-top:184rpx;" :duration="300" @animationfinish="ontabchange"
:style="{height: swiperHeight+'px'}">
<swiper-item class="swiper-item" v-for="(item,i) in tabBars">
<scroll-view class="scroll-v" :class="'list'+(i+1)" enableBackToTop="true" scroll-y>
<slot name='list{{i+1}}'></slot>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
props: {
tabBars: {
type: Array,
default: () => {
return []
}
},
},
data() {
return {
tabIndex: 0,
swiperHeight:0,
scrollInto:'',
};
},
watch:{
},
methods: {
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.tabIndex = index;
this.scrollInto = this.tabBars[index].id;
},
ontabchange(e){
let index = e.detail.current;
this.tabIndex = index;
this.scrollInto = this.tabBars[index].id;
this.$emit('changeTabbar',this.tabIndex)
},
//动态获取高度(swiper组件高度固定,动画获取数据需要动态获取高度)
getElementHeight(element) {
//一定要 this.$nextTick 完成之后在获取dom节点高度
setTimeout(() => {
this.$nextTick(() => {
let query = uni.createSelectorQuery().in(this);
query.select(element).boundingClientRect(data => {
// console.log(111,data)
if (!data) { //如果没获取到,再调一次
this.getElementHeight('.list');
} else {
this.swiperHeight = data.height;
//关闭loading
this.$emit('closeLoading')
}
}).exec()
})
}, 10)
},
}
}
</script>
<style lang="scss" scoped>
.tabs {
flex: 1;
flex-direction: column;
overflow: hidden;
height:100%;
overflow-y: scroll;
.scroll-h {
width: 750rpx;
/* #ifdef H5 */
width: 100%;
/* #endif */
flex-direction: row;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
flex-wrap: nowrap;
background-color: #fff;
}
.uni-tab-item {
/* #ifndef APP-PLUS */
display: inline-block;
/* #endif */
flex-wrap: nowrap;
padding-left: 34rpx;
padding-right: 34rpx;
}
.uni-tab-item-line {
width: 54rpx;
height: 6rpx;
background: #1975F7;
border-radius: 3rpx 3rpx 3rpx 3rpx;
margin: 0 auto;
}
.uni-tab-item-title {
color: #555;
font-size: 30rpx;
height: 60rpx;
line-height: 60rpx;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
}
.uni-tab-item-title-active {
color: #1975F7;
}
.swiper-box {
flex: 1;
}
.swiper-item {
flex: 1;
flex-direction: row;
}
.scroll-v {
flex: 1;
/* #ifndef MP-ALIPAY */
flex-direction: column;
/* #endif */
width: 750rpx;
width: 100%;
}
.tabCenter {
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
2.在界面引入,使用
//引入组件
import tabbarPage from '../components/tabbar/index.vue';
//使用
<tabbar-page :tabBars="tabBarLists" ref="tabBarPage" @changeTabbar="changeTabbar">
<template slot="list1"> //写对应界面的代码 </template>
<template slot="list2"> //写对应界面的代码</template>
<template slot="list3"> //写对应界面的代码</template>
</tabbar-page>
3.注意。如果切换界面对应的是动态数据,swiper因为高度固定,需要获取动态高度
数据请求到之后调用组件接口,代码如下
setTimeout(() => {
this.$nextTick(() => {
this.$refs.tabBarPage.getElementHeight('.list1')
})
}, 10)
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**
**uni-app滑动/点击切换tab组件,动态数据内容获取swiper动态高度**