在做公司小程序的过程当中需要用到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
| Component({ options: { multipleSlots: true },
properties: { tabs: { type: Array, value: [] }, position: { type: String, value: 'top' } },
data: { activeIndex: 0 },
methods: { toggleTab: function (e) { if (this.data.activeIndex === e.currentTarget.dataset.index) { return false; } else { this.setData({ activeIndex: e.currentTarget.dataset.index }) } }, swiperChange: function(e) { var activeIndex = e.detail.current this.setData({ activeIndex }) } } })
|