在做公司小程序的过程当中需要用到tab的功能, 虽然小程序已经有了自带的tab选项组件, 直接在 app.json 文件里面配置即可使用, 奈何产品大大要求tab选项卡必须能够左右滑动还可以点击切换, 以便提高用户体验! 所以呢, 那就只能自己动手封装一个吧!

最终的效果如下图所示:

要求:

  • 1、tab内容区左右滑动切换时,tab标题随即做标记(active)。
  • 2、当active的标题不在当前屏显示时,要使其能显示到当前屏中。

wxml 结构

  • tab内容可左右滑动切换,使用swiper组件实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<view class="tabview">
<view class="tabs {{position == 'top'?'top':'bottom'}}">
<block wx:for="{{tabs}}" wx:key="index">
<view class="tab-son {{activeIndex ==index?'active':''}}" data-index="{{index}}" bindtap='toggleTab'>
<image class='tab-icon' src='{{activeIndex ==index?item.selectedIcon:item.icon}}' mode='aspectFit'></image>
<view class='tab-text'>{{item.name}}</view>
</view>
</block>
</view>
<swiper current="{{activeIndex}}" class="tab-swiper {{position == 'top'?'padding-top':'padding-bottom'}}" bindchange="swiperChange">
<swiper-item wx:for="{{tabs}}" wx:key="{{index}}" class="tab-contents">
<slot name="{{index}}"></slot>
</swiper-item>
</swiper>
</view>
  • 说明:
    • 1、设置data-index属性用于:点击当前项时,通过点击事件toggleTab中处理 e.currentTarget.dataset.index 取到点击的目标值。
    • 2、swiper组件的current组件用于控制当前显示哪一页
    • 3、swiper组件绑定change事件swiperChange,通过e.currentTarget.dataset.index 拿到当前页

wxss 样式部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.tabview {
width:100%;
height: 100%;
}
.tabs {
width:100%;
display: flex;
position:fixed;
left:0;
background-color:#f8f8f8;
height:110rpx;
font-size:24rpx;
z-index:999;
text-align:center;
margin-top: 10rpx;
}
.tabs .active {
color: #7b58a7;
}
.top {
top: 0;
box-shadow:4px 4px 10px #f2f2f2;
}
.bottom {
bottom: 0;
border-top: 1px solid #d6d5d5;
}
.tab-son {
display:flex;
flex-direction: column;
flex: 1;
}
.tab-icon {
width: 64rpx;
height: 50rpx;
margin: 12rpx auto 10rpx;
}
.tab-swiper {
height: 100%;
box-sizing: border-box;
}
.padding-top {
padding-top: 110rpx;
}
.padding-bottom {
padding-bottom: 110rpx;
}

js 部分

  • 微信小程序在开发时个人感觉挺像vue的,以数据驱动视图的更新。但是在小程序中,不能直接操作dom,当然也不能使用jquery之类的库。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// views/tabView.js
Component({
// 配置
options: {
multipleSlots: true //在组件定义时的选项中启用多slot支持
},
/**
* 组件的属性列表
*/
properties: {
tabs: {
type: Array,
value: []
},
position: {
type: String,
value: 'top'
}
},

/**
* 组件的初始数据
*/
data: {
activeIndex: 0
},

/**
* 组件的方法列表
*/
methods: {
// 点击切换tab
toggleTab: function (e) {
if (this.data.activeIndex === e.currentTarget.dataset.index) {
return false;
} else {
this.setData({
activeIndex: e.currentTarget.dataset.index
})
}
},
// 滑动切换tab
swiperChange: function(e) {
var activeIndex = e.detail.current
this.setData({
activeIndex
})
}
}
})