选项卡在我们的日常开发中,使用的还是蛮多的,但是微信小程序中却没有直接提供选项卡组件,不过我们可以变通通过 scroll-view 和 swiper 组件来实现一个选项卡的功能。
需求:
实现一个选项卡,选项卡的标题可能会比较多,当超过一屏时,需要可以滚动显示。选项卡的内容需要左右滑动显示。
实现思路:
1、标题较多,使用 scroll-view 组件来显示即可。
2、内容滑动,使用 swiper 组件来显示。
效果图:
代码实现:
1、页面布局 tabs.wxml 文件的编写
<view>
<scroll-view scroll-x="{{true}}" class='top-nav-container' scroll-left="{{scrollLeft}}">
<block wx:for="{{topNavs}}" wx:key='{{*this}}'>
<view class='tab-item {{currentActiveNavIndex == index ? "active":""}}' data-current-index='{{index}}' bindtap='topNavChange'>
{{item}}
</view>
</block>
</scroll-view>
<swiper bindchange="swiperChange" class='swiper-container' current='{{currentActiveNavIndex}}' bindtouchmove="touchmove">
<block wx:for="{{topNavs}}" wx:key='{{*this}}'>
<swiper-item style="overflow:scroll">
<view>{{item}}</view>
</swiper-item>
</block>
</swiper>
</view>
注意:
1、scroll-view scroll-x=true 表示开启横向滚动
2、scroll-view scroll-left 表示表示横向滚动条的位置
3、swiper 组件中的 current 表示当前所在滑块的 index,给这个变量赋值,可以直接滑动到这一屏。
2、样式编写 tabs.wxss 文件的编写
.top-nav-container{
width: 100%;
height: 60rpx;
line-height: 60rpx;
font-size: 14px;
background-color: #CCC;
vertical-align: middle;
white-space: nowrap;
}
.top-nav-container .tab-item{
display: inline-block;
margin: 0rpx 30rpx;
}
.top-nav-container .tab-item.active{
color: rgb(48, 121, 255);
border-bottom: 4rpx solid #F00;
line-height: 52rpx;
}
.swiper-container{
height: calc(100vh - 60rpx);
background-color: #00b26a;
font-size: 14px;
}
3、js 控制 tabs.js 文件的编写
Page({
data: {
/**
* 导航数据
*/
topNavs: ['直播', '推荐', '世界杯', '生活', '萌宠', '娱乐', '游戏', '常用', '11111', '22222', '3333', '4444', '5555', '6666'],
/**
* 当前激活的当航索引
*/
currentActiveNavIndex: 0,
/**
* 上一个激活的当航索引
*/
prevActiveNavIndex: -1,
/**
* scroll-view 横向滚动条位置
*/
scrollLeft: 0
},
/**
* 顶部导航改变事件,即被点击了
* 1、如果2次点击同一个当航,则不做处理
* 2、需要记录本次点击和上次点击的位置
*/
topNavChange: function(e) {
var nextActiveIndex = e.currentTarget.dataset.currentIndex,
currentIndex = this.data.currentActiveNavIndex;
if (currentIndex != nextActiveIndex) {
this.setData({
currentActiveNavIndex: nextActiveIndex,
prevActiveNavIndex: currentIndex
});
}
},
/**
* swiper滑动时触发
* 1、prevIndex != currentIndex 表示的是用手滑动 swiper组件
* 2、prevIndex = currentIndex 表示的是通过点击顶部的导航触发的
*/
swiperChange: function(e) {
var prevIndex = this.data.currentActiveNavIndex,
currentIndex = e.detail.current;
this.setData({
currentActiveNavIndex: currentIndex
});
if (prevIndex != currentIndex) {
this.setData({
prevActiveNavIndex: prevIndex
});
}
this.scrollTopNav();
},
/**
* 滚动顶部的导航栏
* 1、这个地方是大致估算的
*/
scrollTopNav: function() {
/**
* 当激活的当航小于4个时,不滚动
*/
if (this.data.currentActiveNavIndex <= 3 && this.data.scrollLeft >= 0) {
this.setData({
scrollLeft: 0
});
} else {
/**
* 当超过4个时,需要判断是向左还是向右滚动,然后做相应的处理
*/
var plus = this.data.currentActiveNavIndex > this.data.prevActiveNavIndex ? 60 : -60;
this.setData({
scrollLeft: this.data.scrollLeft + plus
});
}
console.info(this.data.currentActiveNavIndex, this.data.prevActiveNavIndex, this.data.scrollLeft);
}
})
注意:
1、 需要注意的地方可以看代码中的注释
完整代码:
选项卡代码:https://gitee.com/huan1993/weixin_mini_program_study/tree/master/pages/tabs