<view class="tab-page-root">
<view class="tabbar-header flex_align-center">
<view v-for="(item, i) in tabs" @tap="tabTap(i)" class="flex1" :key="item">{{ item }}</view>
</view>
<view :style="{ left: tabLineLeft + 'px' }" class="tabbar-line"></view>
<view
class="tabbar-content"
:style="'transform:translateX(' + xPercent + '%);transition:transform ' + pageDuration + 'ms;'"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
>
<view v-for="(item, i) in tabs" :key="item" :style="'transform:translateX(' + i * 100 + '%);height:' + height + 'px;'" class="tabbar-page">
<!-- <slot name="page" :i="i" :pageData="pageData"></slot> -->
<view class="item0" v-if="i == 0"><view v-for="(item, index) in list1" :key="index">321232312146465458574888784654655654</view></view>
<view class="item1" v-if="i == 1"><view v-for="(item, index) in list2" :key="index">321232312146465458574888784654655654</view></view>
<view class="item2" v-if="i == 2"><view v-for="(item, index) in list3" :key="index">321232312146465458574888784654655654</view></view>
<view class="item3" v-if="i == 3"><view v-for="(item, index) in list4" :key="index">321232312146465458574888784654655654</view></view>
</view>
</view>
const safeAreaWidth = uni.getSystemInfoSync().safeArea.width;
let tabbarLineWidth,
yAxisGap = 8;
// #ifdef H5
yAxisGap = 6;
// #endif
export default {
components: {
// pag
},
data() {
let tabs = ['作品', '喜欢', '收藏', '评论'];
let pageData = [['AAA', 'BBBB'], ['CCC', 'DD']];
return {
tabs,
pageData,
tabIndex: 0,
xPercent: 0,
startPageX: 0,
startPageY: 0,
yScrollTimes: 0,
yScrolling: false,
positive: 1,
pageDuration: 0,
tabLineLeft: safeAreaWidth / tabs.length - 17,
height: 0,
list1: [{}, {}, {}, {}, {}, {}, {}, {}],
list2: [{}, {}, {}],
list3: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
list4: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
};
},
mounted() {
uni.createSelectorQuery()
.in(this)
.select('.tabbar-line')
.boundingClientRect(data => {
// data - 各种参数
tabbarLineWidth = data.width;
this.tabLineLeft = (safeAreaWidth / this.tabs.length - tabbarLineWidth) / 2;
})
.exec();
this.getheight();
},
methods: {
tabSwitch(i) {
if (i == 1) {
//注意:以下是tab页加载数据的方式
this.lists.splice(1, 1, ['GGGG']);
}
},
getheight() {
console.log(this);
let that = this;
let theNode = uni.createSelectorQuery().select('.item'+ that.tabIndex);
theNode.boundingClientRect((data)=>{
this.height = data.height
console.log(this);
console.log(data)
}).exec()
},
tabTap(i) {
this.getheight();
if (this.tabIndex != i) {
this.pageDuration = 0;
this.xPercent = -i * 100;
this.tabIndex = i;
this.tabLineLeft = ((i + 1 / 2) * safeAreaWidth) / this.tabs.length - tabbarLineWidth / 2;
this.loadTabPage();
}
},
touchstart(e) {
this.startPageX = e.changedTouches[0].pageX;
this.startPageY = e.changedTouches[0].pageY;
this.startXPercent = this.xPercent;
},
touchmove(e) {
this.yScrollTimes++;
if (this.yScrollTimes == 1 && Math.abs(e.changedTouches[0].pageY - this.startPageY) > yAxisGap) {
this.yScrolling = true;
}
if (this.yScrolling) return;
this.pageDuration = 0;
const relativeXPercent = ((e.changedTouches[0].pageX - this.startPageX) * 100) / safeAreaWidth;
if (this.relativeXPercent < relativeXPercent) {
this.positive = -1;
} else {
this.positive = 1;
}
const xPercent = relativeXPercent + this.startXPercent;
if (xPercent >= 0) {
this.xPercent = 0;
} else if (xPercent <= (1 - this.tabs.length) * 100) {
this.xPercent = (1 - this.tabs.length) * 100;
} else {
this.xPercent = xPercent;
}
this.relativeXPercent = relativeXPercent;
},
touchend() {
if (-this.xPercent % 100 < 10 || (this.relativeXPercent < 0 && this.positive < 0)) {
this.pageDuration = 80;
this.tabIndex = Math.floor(-this.xPercent / 100);
} else if (-this.xPercent % 100 > 90 || (this.relativeXPercent > 0 && this.positive > 0)) {
this.pageDuration = 80;
this.tabIndex = Math.floor(-this.xPercent / 100 + 1);
} else {
this.pageDuration = 300;
this.tabIndex += this.positive;
this.tabLineLeft = ((this.tabIndex + 1 / 2) * safeAreaWidth) / this.tabs.length - tabbarLineWidth / 2;
this.loadTabPage();
}
this.xPercent = -this.tabIndex * 100;
this.yScrolling = false;
this.yScrollTimes = 0;
},
// 切换选项卡的 相应函数
loadTabPage() {
// 点击选项卡 重新获取高度
this.getheight();
// this.$emit('tabSwitch', this.tabIndex);
}
}
};
?注意: calss命名 这个跟获取高度有重要关系 !!!
.tab-page-root {
position: absolute;
width: 100%;
}
.tabbar-header {
text-align: center;
line-height: 72upx;
}
.tabbar-line {
position: relative;
left: 96upx;
width: 80rpx;
height: 8rpx;
background-color: #000000;
transition: left 300ms;
}
.tabbar-content {
min-height: calc(100% - 83upx);
}
.tabbar-page {
position: absolute;
width: 100%;
height: 100%;
overflow-y: auto;
}
|