小程序如何写一个优美的tab选项卡?
最近有位朋友刚学小程序,于是乎给我传了他写的一个tab选项卡,昨天晚上恰有空闲,于是改了一下
写选项卡的方法有很多,方法也特别简单,本文就介绍一下就客户体验而言如何让写一个用户体验不错的选项卡
效果如下gif所示
wxml结构一共分为两个部分一个是tab头部和swiper构成的内容部分,用swiper做切换内容的盒子的好处是它能让用户的体验变得更好,出现如上所示的效果,当我点击tab头部是,下面的内容也会相应的切换,当滑动下方swiper的时候上方的tab头部相应的也会被点亮
wxml如下:
<view class="content">
<!--头部tab切换部分start-->
<view class="menu">
<view class="{{currentTab==index?'select':'default'}}" wx:for="{{switchtab}}" wx:key='' data-current="{{index}}" catchtap="switchNav">{{item.name}}</view>
</view>
<view class="explain-box">
<text class="explain">使用说明</text>
<text class="iconfont icon-wenhao"></text>
</view>
<!--头部tab切换部分end-->
<!--切换内容部分start-->
<swiper current='{{currentTab}}' bindchange="tabChange" class='mySwiper'>
<block wx:for="{{coupons}}" wx:key="">
<swiper-item>
<block wx:for="{{item}}" wx:key="" wx:for-item="spItem">
<view class="item">
<view class="left">
<view class="left-top">
<text class="rmb">¥</text>
<text class="price">{{spItem.price}}</text>
</view>
<view class="left-bottom">
<text class="label">{{spItem.condition}}</text>
</view>
</view>
<view class="right">
<text class="item-1">{{spItem.goods}}</text>
<text class="item-2">优惠券描述</text>
<text class="item-3">{{spItem.way}}</text>
<text class="item-4">{{spItem.date}}</text>
</view>
</view>
</block>
</swiper-item>
</block>
</swiper>
<!--切换内容部分end-->
</view>
在swiper组件中一共用过两个属性,一个是current,另一个是bindchange
阅读过官方文档的朋友都知道current是指当前所在滑块的 index,bindchange是指current 改变时会触发 change 事件,event.detail = {current: current, source: source}
js文件如下:
Page({
data: {
switchtab: [{
name: '未使用',
_type: 'notUsed'
}, {
name: '已使用',
_type: 'alreadyUsed'
},
{
name: '已过期',
_type: 'expired'
}
],
currentTab: 0,
coupons: []
},
onLoad: function (options) {
this.setData({
coupons: this.loadCoupons()
});
},
//tab切换函数,让swiper当前滑块的current的index与tab头部index一一对应
switchNav: function (e) {
var index = e.target.dataset.current;
if (this.data.currentTab == index) {
return false;
} else {
this.setData({
currentTab: index
});
}
},
//滑动swiper切换,让swiper当前滑块的current的index与tab头部index一一对应
tabChange(e) {
this.setData({
currentTab: e.detail.current
})
},
//自定义数据函数
loadCoupons: function () {
let switchtab = this.data.switchtab,
coupons = [{
id: "1",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券;",
way: "限无人机、数码、潮玩",
date: "2017.3.22-2017.12.22",
_type: "notUsed"
}, {
id: "1",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券;",
way: "限无人机、数码、潮玩",
date: "2017.3.22-2017.12.22",
_type: "notUsed",
}, {
id: "1",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券",
way: "限无人机、数码、潮玩;",
date: "2017.3.22-2017.12.22",
_type: "notUsed",
}, {
id: "1",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券",
way: "限无人机、数码、潮玩;",
date: "2017.3.22-2017.12.22",
_type: "notUsed"
}, {
id: "1",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券",
way: "限无人机、数码、潮玩;",
date: "2017.3.22-2017.12.22",
_type: "notUsed"
}, {
id: "2",
price: "200",
condition: "无门槛",
goods: "新用户 20元优惠券",
way: "限无人机、数码、潮玩;",
date: "2017.3.22-2017.12.22",
_type: "alreadyUsed"
}, {
id: "2",
price: "100",
condition: "满500可用",
goods: "仅可购买网络品类指定商品",
way: "全平台",
date: "2017.3.22-2017.12.22",
_type: "alreadyUsed",
}, {
id: "2",
price: "100",
condition: "满500可用",
goods: "仅可购买网络品类指定商品",
way: "全平台",
date: "2017.3.22-2017.12.22",
_type: "alreadyUsed",
}, {
id: "3",
price: "200",
condition: "满200可用",
goods: "仅可购买网络品类指定商品",
way: "全平台",
date: "2017.3.22-2017.12.22",
_type: "expired"
}];
//这里是根据tab头部的数据来重建一个数组,使数组的内容与tab一一对应
var result = new Array();
for (var n = 0; n < switchtab.length; n++) {
let minArr = []
for (var i = 0; i < coupons.length; i++) {
//根据类型来区分自定义的内容属于哪个tab下面的
if (coupons[i]._type == switchtab[n]._type) {
minArr.push(coupons[i]);
}
}
result.push(minArr)
}
return result;
},
onReady: function () {
},
onShow: function () {
},
onHide: function () {
},
onUnload: function () {
},
onPullDownRefresh: function () {
},
onReachBottom: function () {
}
})
wxss如下:
@import "../../lib/style/font.wxss";
.content {
background-color: #fff;
}
.menu {
width: 100%;
display: flex;
box-sizing: border-box;
border-bottom: 1px solid #f2f2f2;
z-index: 11;
}
.menu view {
margin: 0rpx auto;
height: 88rpx;
line-height: 88rpx;
font-size: 28rpx;
color: #434343;
}
.menu .mr {
border-right: 0rpx;
}
.select {
position: relative;
}
.select:after {
position: absolute;
left: 7rpx;
bottom: 0rpx;
content: "";
width: 70rpx;
height: 8rpx;
background-color: #3795ff;
border-radius: 4px 4px 0 0;
}
.body {
width: 100%;
box-sizing: border-box;
}
.body .explain-box {
display: flex;
justify-content: flex-end;
height: 80rpx;
line-height: 80rpx;
box-sizing: border-box;
padding: 0rpx 30rpx;
z-index: 12;
}
.explain-box text {
font-size: 24rpx;
color: #3795ff;
}
.explain-box .explain {
margin-right: 8rpx;
}
.explain-box .icon-wenhao {
vertical-align: middle;
line-height: 82rpx;
}
.item {
background-color: #3795ff;
width: 690rpx;
margin: 0 auto;
margin-bottom: 20rpx;
border-radius: 10rpx;
display: flex;
padding: 20rpx 0rpx;
box-sizing: border-box;
}
.item .left {
width: 180rpx;
height: 140rpx;
border-right: 1px solid #7fbbff;
}
.item .left .left-top {
text-align: center;
height: 94rpx;
color: #fff;
}
.item .left .left-top .rmb {
font-size: 34rpx;
}
.item .left .left-top .price {
font-size: 60rpx;
}
.left-bottom {
height: 32rpx;
display: flex;
justify-content: center;
}
.label {
height: 32rpx;
line-height: 32rpx;
padding: 0rpx 18rpx;
font-size: 24rpx;
color: #3795ff;
text-align: center;
background-color: #fff;
border-radius: 200rpx;
}
.item .right {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 56rpx;
}
.item-1 {
font-size: 32rpx;
line-height: 32rpx;
color: #fff;
}
.item-2 {
font-size: 24rpx;
line-height: 32rpx;
color: #1b67bd;
}
.item-3, .item-4 {
margin-top: 13rpx;
font-size: 24rpx;
line-height: 32rpx;
color: #fff;
}
.item-4 {
margin-top: 0rpx;
}
.mySwiper {
position: fixed;
width: 100%;
height: 100%;
top: 0;
box-sizing: border-box;
padding: 170rpx 0rpx 0rpx 0rpx;
z-index: -1;
}
.mySwiper swiper-item {
overflow-y: scroll;
}
欢迎大家留言!