<template>
<view style="height: 100vh;background: #C7C7C7;">
<!-- 顶部tab导航部分
1.scroll-into-view="{{showView}}" 这里需要借助这个属性来指定显示tab
2.scroll-left="{{navScrollLeft}}" 借助left来使scroll能让遮盖的tab动画显出
-->
<scroll-view class="pick_tab_box" scroll-x scroll-into-view="{{showView}}" scroll-with-animation scroll-left="{{navScrollLeft}}">
<view data-id="{{item.title}}" wx:for="{{swiperItems}}" class="{{currentTab == item.title ? 'tab_active' : ''}} tabItem" bindtap='switchTab'>{{item.title}}</view>
</scroll-view>
<view class="btn-more" @tap="openMore">更多</view>
<!-- 用于超过5个tab时展示更多-->
<view wx:if="{{showMore}}" style="margin-top: 47px;position: absolute;z-index: 333;right: 0;">
<button @tap='switchTab' data-id="{{item.title}}" wx:for="{{swiperItems}}">{{item.title}}</button>
</view>
<!-- 使用swiper组件来对应不同的tab
需要注意的是这里必须给swiper加固定高度 并且是固定定位-tab高度 否则下面的子节点无法全撑开
-->
<swiper indicator-dots="{{false}}" current="{{currents}}" bindchange="swiperChange" style="height: {{windowHeight - 47}}px" class="swiperBox">
<block wx:for="{{swiperItems}}">
<swiper-item>
<!-- 这里给每个tab展示页都增加滚动组件,方便进行上来加载数据-->
<scroll-view
style="height: 100%;"
scroll-y
bindscroll="scroll"
bindscrolltolower = "onRBottom"
scroll-with-animation
lower-threshold="1"
scroll-top="{{scrollTop0}}px"
>
<view class="swiper-item" style="background: {{item.bg}};text-align: center;font-size: 25px;">
{{mockData}}
</view>
</scroll-view>
</swiper-item>
</block>
</swiper>
</view>
</template>
<script>
import wepy from 'wepy'
//模拟数据
let mockData = `测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发
测试数据第三方的撒范德萨发大幅度暗室逢灯发达发`
export default class categoryScroll extends wepy.page {
config = {
navigationBarTitleText: '测试'
}
components = {}
data = {
currentTab:'tab1',//标记当前tab
showView:'',
navScrollLeft:0,//滚动组件距离左侧位置
showMore:false,//是否展示tab更多按钮
currents:0,
windowHeight:0,//屏幕高度
scrollTop0:0,
mockData:'',
isLoading:false,//用于标记是否数据加载中,防止重复请求
pageData:{//每个tab对应页的数据结构
tab1:{
data:{},
pageIndex:0,
total:0
},
tab2:{
data:{},
pageIndex:0,
total:0
},
//...
},
swiperItems:[
{
title:'tab1',
bg:'#b3faa8'
},
{
title:'tab2',
bg:'green'
},
{
title:'tab3',
bg:'yellow'
},
{
title:'tab4',
bg:'#7d86fa'
},
{
title:'tab5',
bg:'white'
},
{
title:'tab6',
bg:'pink'
},
{
title:'tab7',
bg:'#fa425f'
},
]
}
computed = {}
methods = {
/*
@desc:点击tab操作
*/
switchTab(e){
let ids = e.currentTarget.dataset.id;
let index = ids.replace('tab','');
//这里可以根据下标来分别请求不同page的数据
this.currents = index-1;
this.navScrollLeft = (index-2)*45;
this.currentTab = ids;
this.showMore = false;
this.showView = ids;
this.$apply();
},
openMore(){
this.showMore = true
},
/*
@desc:手动滑动swiper到下一个swiper-item显示时触发
*/
swiperChange(e){
let index = e.detail.current/1+1;
let _this = this;
//这里可以根据下标来分别请求不同page的数据
//这里拿第tab2做数据加载模拟
if(index==4){
wx.showLoading({
title: '数据请求中',
mask: true
});
setTimeout(()=>{
wx.hideLoading();
_this.mockData+=mockData;
_this.$apply()
},3000)
}
this.navScrollLeft = (index-2)*45;
this.showView = 'tab'+index;
this.currentTab = 'tab'+index;
this.$apply()
},
scroll(e){
// console.log("滚动事件:"+e)
},
onRBottom(){
let _this = this;
if(!this.isLoading){
_this.isLoading = true;
//模拟请求
wx.showLoading({
title: '数据请求中',
mask: true
});
setTimeout(()=>{
_this.mockData+=mockData;
wx.hideLoading();
_this.isLoading = false;
//这里一定要记得加上$apply方法出行渲染页面,否则高度没更新,会导致scroll组件无法识别新高度而重复触发底部请求
_this.$apply()
},3000)
}
}
}
systemType () {
const systemInfo = wx.getSystemInfoSync();
const rate = 750 / systemInfo.windowWidth;
this.windowHeight = systemInfo.windowHeight * rate;
this.$apply();
}
onLoad() {
// 页面准备完成之后获取每个分类距离顶部的高度, 存储在数组productsTop中
this.systemType()
}
}
</script>
<style lang="less">
.pick_tab_box {
position: fixed;
top: 0;
display: flex;
align-items: center;
white-space: nowrap;
width: 88%;
background: white;
z-index: 22;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.tabItem {
box-sizing: border-box;
padding: 20rpx 50rpx;
display: inline-flex;
justify-content: center;
font-size: 30rpx;
}
.tab_active {
color: #fa425f;
position: relative;
}
.tab_active::after{
content: '';
bottom: 0;
left: 50%;
transform: translateX(-50%);
position: absolute;
height: 3px;
width: 30px;
border-radius: 8px;
background: linear-gradient(to right,rgba(225, 215, 69, 25) , greenyellow);
}
.btn-more{
position: fixed;
right: 0;
top: 0;
background: rgba(0,0,0,.3);
height: 47px;
line-height: 47px;
width: 51px;
text-align: center;
color: white;
z-index: 333;
box-shadow: -1px 0px 0px rgba(0,0,0,0.1);
}
.swiperBox{
position: fixed;
top: 47px;
width: 100%;
left: 0;
bottom: 0
}
.swiper-item{
min-height: 100vh;
padding: 10px 10px 100px 10px;
}
</style>