300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 微信小程序-tab切换(scroll-view + swiper)

微信小程序-tab切换(scroll-view + swiper)

时间:2019-09-01 12:36:25

相关推荐

微信小程序-tab切换(scroll-view + swiper)

话不多说,先上一张效果图(没买会员,有水印,勿介意),如果是你想要的效果,继续往下看

原先做百度小程序的时候有现成的tab切换组件,然后改做微信小程序的时候,发现没有现成的组件是上图的效果,所以自己手动写了一个。

我这边的tab切换用的是scroll-view + swiper。切换选项的是scroll-view,如果不用scroll-view的话,在切到第五个的时候,第六个不会自动滑出来,用户体验感不好。底下使用swiper也是为了让内容切换的时候,有滑动的效果,提高用户体验。

一、初步完成tab切换

tab选项的处理

1.给每个tab选项添加一个data-current的属性,绑上当前是第几个选项。(注意:这边的第1个绑的是0,第2个绑的是1,…)

2.给选中的tab选项添加一个类on(里面写选中时的样式)

3.给tab选项添加一个切换事件,swichNav

tab内容的处理

1.swiper有一个current属性,值为当前是第几个元素,可以利用这一点,传一个数字currentTab(当前应该显示第几个)给current,从而显示对应的内容

2.给swiper添加切换事件,bindChange

swichNav事件的处理

1.先在data中给currentTab一个默认值0,因为一般都是默认显示第一个.

2.比较当前点击的元素的data-current和当前选中的tab选项(即currentTab):

如果两个值一样,说明点击的就是当前选中的,就不做处理,

如果两个值不一样,就要将currentTab值改成当前点击的元素的data-current

swichNav事件的处理

将当前的currentTab(当前应该显示第几个)传给current

wxml代码:

<view class="swiper-tab"><scroll-view scroll-x="true" show-scrollbar="false" scroll-with-animation="true" style="width: 100%;white-space: nowrap;"><block wx:for="{{provList}}" wx:key="i"><view class="swiper-tab-list {{currentTab==index ? 'on' : ''}}" data-current="{{index}}" bindtap="swichNav">{{item.name}}</view></block></scroll-view><swiper current="{{currentTab}}" class="swiper-box" duration="300" bindchange="bindChange" style="height: {{tabsheight}};"><block wx:for="{{cityList}}" wx:for-item="city" wx:key="n"><swiper-item><view class="list"><block wx:for="{{city}}" wx:key="u"><view class="city-item"><image class="img" src="{{item.img}}"></image><view class="text">{{item.city}}</view></view></block></view></swiper-item></block></swiper></view>

js代码:

Page({data: {currentTab:0},swichNav: function( e ) {var that = this;if( this.data.currentTab === e.target.dataset.current ) {return false;} else {that.setData( {currentTab: e.target.dataset.current})}},bindChange: function( e ) {var that = this;that.setData( {currentTab: e.detail.current});},})

二、实现tab滚动条滑动

想要让tab滚动条滑动,可以利用scroll-view中的 scroll-left属性。我们判断当前选中的个数是否是第5个,如果是,我们将当前的个数*tab选项的宽度赋给scroll-left.

wxml代码:

<scroll-view scroll-left="{{navScrollLeft}}" scroll-x="true" show-scrollbar="false" scroll-with-animation="true"style="width: 100%;white-space: nowrap;">

js代码:

swichNav: function( e ) {var that = this;if( this.data.currentTab === e.target.dataset.current ) {return false;} else {that.setData( {currentTab: e.target.dataset.current,navScrollLeft:e.target.dataset.current >= 4 ? ((e.target.dataset.current) * 60) : 0//判断当前选中的个数是否是第5个})}},bindChange: function( e ) {var that = this;that.setData( {currentTab: e.detail.current,navScrollLeft:e.detail.current >= 4 ? ((e.detail.current) * 60) : 0//判断当前选中的个数是否是第5个});}

三、Swiper的高度自适应

swiper的高度不能自适应,默认高度150px,如果每个列表的长度不一样,也不能固定写死一个值,需要计算得出。网上有很多推荐根据列表的长度*元素的高度得到swiper的高度,但是这个方法只适用于swiper-item里面只有一个列表的,要是swiper-item里面有好几个列表的,就算不过来了。

我利用了SelectorQuery NodesRef.boundingClientRect(function callback)这个API获取一个元素的高度(我们可以把swiper-item里面有好几个列表包到这个元素里),然后把这个高度传给swiper。

这里需要注意的一点是,我们swiper有好多个swiper-item,我们必须给这个元素标上编号,以方便获取对应swiper-item的高度。

wxml代码:

<swiper current="{{currentTab}}" class="swiper-box" duration="300" bindchange="bindChange" style="height: {{tabsheight}};">//tabsheight就是计算后的值<block wx:for="{{cityList}}" wx:for-item="city" wx:key="n"><swiper-item><view class="list list{{index}}">//list{{index}}就是给每个list标上序号/*好多个列表*/</view></swiper-item></block></swiper>

js代码:

data: {tabsheight:'450px'//默认高度},//计算swiper高度方法(在切换的时候调用)tabsHeight(element){let that = this;let query = wx.createSelectorQuery();//必须要先创建一个查询query.select(element).boundingClientRect(function(rect){that.setData({tabsheight:rect.height + 'px'});}).exec();},swichNav: function( e ) {var that = this;if( this.data.currentTab === e.target.dataset.current ) {return false;} else {that.setData( {currentTab: e.target.dataset.current,navScrollLeft:e.target.dataset.current >= 4 ? ((e.target.dataset.current) * 60) : 0})}that.tabsHeight('.list'+e.target.dataset.current);//查询哪一个元素},bindChange: function( e ) {var that = this;that.setData( {currentTab: e.detail.current,navScrollLeft:e.detail.current >= 4 ? ((e.detail.current) * 60) : 0});that.tabsHeight('.list'+e.detail.current);//查询哪一个元素},})

因为这边的列表不是从接口里得到的,所以data中给一个默认高度,用于第一个swiper-item的渲染。如果列表是从接口里得到的,就不需要在data中加tabsheight了,直接得到值的时候调用一次tabsHeight方法就行。如果你遇到没有第一次的高度没有加上,是因为还没有渲染完成就调用tabsHeight方法了,所以给它加个定时器,等渲染完成,再计算高度

setTimeout(() => {that.tabsHeight('.list0');},1000)

完整代码

wxml代码:

<view class="container"><view class="swiper-tab"><scroll-view scroll-x="true" show-scrollbar="false" scroll-with-animation="true" scroll-left="{{navScrollLeft}}" style="width: 100%;white-space: nowrap;"><block wx:for="{{provList}}" wx:key="i"><view class="swiper-tab-list {{currentTab==index ? 'on' : ''}}" data-current="{{index}}" bindtap="swichNav">{{item.name}}</view></block></scroll-view></view><swiper current="{{currentTab}}" class="swiper-box" duration="300" bindchange="bindChange" style="height: {{tabsheight}};"><block wx:for="{{cityList}}" wx:for-item="city" wx:key="n"><swiper-item><view class="list list{{index}}"><block wx:for="{{city}}" wx:key="u"><view class="city-item"><image class="img" src="{{item.img}}"></image><view class="text">{{item.city}}</view></view></block></view></swiper-item></block></swiper><view>底部</view></view>

wxss代码:

.swiper-tab{width: 100%;text-align: center;line-height: 80rpx;}.swiper-tab-list{font-size: 30rpx;display: inline-block;min-width: 18%;max-width: 18%;margin: 0 1%;}.on{ color: black;font-weight: bold;border-bottom: 4rpx solid black;}.swiper-box{display: block;height: 700px;width: 100%;margin-top: 10px;}.city-item{width: 100%;display: flex;flex-flow: row nowrap;margin-bottom: 10px;}.img{width: 40%;height: 100px;}.text{width: 60%;display: flex;justify-content: center;align-items: center;font-size: 24px;border: 1px solid #ddd;box-sizing: border-box;}

js代码:

Page({data: {currentTab:0,tabsheight:'450px',provList:[{"name":"江苏"},{"name":"浙江"},{"name":"上海"},{"name":"河南"},{"name":"河北"},{"name":"重庆"},{"name":"天津"},{"name":"广东"},],cityList:[[{"img":"/imgs/default.jpg","city":"南京"},{"img":"/imgs/default.jpg","city":"苏州"},{"img":"/imgs/default.jpg","city":"南通"},{"img":"/imgs/default.jpg","city":"无锡"}],[{"img":"/imgs/default.jpg","city":"杭州"},{"img":"/imgs/default.jpg","city":"宁波"},{"img":"/imgs/default.jpg","city":"温州"}],[{"img":"/imgs/default.jpg","city":"上海"}],[{"img":"/imgs/default.jpg","city":"郑州"},{"img":"/imgs/default.jpg","city":"开封"},{"img":"/imgs/default.jpg","city":"洛阳"},{"img":"/imgs/default.jpg","city":"周口"}],[{"img":"/imgs/default.jpg","city":"石家庄"},{"img":"/imgs/default.jpg","city":"唐山"},{"img":"/imgs/default.jpg","city":"秦皇岛"}],[{"img":"/imgs/default.jpg","city":"重庆"}],[{"img":"/imgs/default.jpg","city":"天津"}],[{"img":"/imgs/default.jpg","city":"广州"},{"img":"/imgs/default.jpg","city":"深圳"}]]},tabsHeight(element){let that = this;let query = wx.createSelectorQuery();query.select(element).boundingClientRect(function(rect){that.setData({tabsheight:rect.height + 'px'});}).exec();},swichNav: function( e ) {var that = this;if( this.data.currentTab === e.target.dataset.current ) {return false;} else {that.setData( {currentTab: e.target.dataset.current,navScrollLeft:e.target.dataset.current >= 4 ? ((e.target.dataset.current) * 60) : 0})}that.tabsHeight('.list'+e.target.dataset.current);},bindChange: function( e ) {var that = this;that.setData( {currentTab: e.detail.current,navScrollLeft:e.detail.current >= 4 ? ((e.detail.current) * 60) : 0});that.tabsHeight('.list'+e.detail.current);},})

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。