下面来详细讲解,微信小程序如何实现tab切换功能,如下图所示:
在wxml文件里面,搭建结构。其中,tab盒子是tab整体,btns里面的view是切换按钮,cons里面的view是切换的盒子内容。
把切换按钮btns和内容cons渲染出来。在js文件里面书写数据,并且在wxml文件里面通过wx:for进行列表渲染输出。
通过d性布局去书写样式。添加cur当前类名去控制当前按钮的样式和当前显示的内容盒子。
注意微信小程序使用的是rpx可以自适应的单位,规定所有屏幕宽度为750rpx,在iPhone6设备屏幕宽度换算是2rpx=1px。
逻辑层添加了active数据控制当前显示盒子。
wxml要书写判断验证去控制盒子是否有cur类名。
上面表达式表示,如果当前项的索引值index等于数据active,则此项有cur这个类名,否则就没有。注意cur类名是控制当前按钮样式和当前显示内容盒子的。
有cur这个类名的按钮会显示当前的样式,有cur这个类名的内容盒子是显示的,但是否有这个类名是通过active这个数据决定的。所以最后我们只需要把active这个数据的值修改成用户点击按钮的索引值即可实现tab切换功能。
首先要给按钮btn自定义索引值等于循环当前项的index,微信小程序给组件自定义索引值是通过在组件身上添加data-index=”{{index}}”属性,然后在js里面即可通过事件对象里面的e.currentTarget.dataset.index属性获取用户点击按钮的索引值。
给按钮自定义索引值和绑定事件,绑定点击事件通过给按钮组件添加属性bindtap=“函数名”,此处设置函数名为toggle。
把active的值设置为用户点击按钮的索引值,即可实现tab切换功能。
e.currentTarget.dataset.index获取用户点击按钮的索引值,微信小程序通过this.setData()去修改data里面的数据内容。
微信小程序Swiper做Tab切换,带tab切换动画
小程序中我们做tab切换一般情况下可以做点击切换,但是有Swiper组件,其实我们也可以做滑动切换
监听Swiper的bindchange,我们就可以在切换时改变tab的选装状态达到切换的目的。
但是这样的方式tab的切换方式是跳转式的,体验不是很好。于是就有了这个demo,我们一步步优化切换体验。
首先:利用flex布局,做出tab区域,如果tab选项卡很多可以使用Scroll-view;一般的跳转式的tab用boder-bottom实现就好,这里我们加了一个“navbar-slider”,加上translateX动画实现平移切换。
然后:计算出每个tabItem的宽度,和每个item距离0坐标的距离;下中50是slider的宽度,对应上面“width:50px”
关联:1、监听item点击,切换swiper;2、监听swiper切换改变slider位置和tab显示
效果展示如下:
现在我们已经实现了,Swiper和tab的带动画联动,但是我们可以发现,我们的切换动画是在切换之后进行的,我们这里还可以继续优化。
swiper在切换时可以监听bindtransition,swiper-item 的位置发生改变时会触发 transition 事件,event.detail = {dx: dx, dy: dy},dx则是平移的偏移量,我们可以通过这个监听来实时设置slider的位置。
切换后校正slider的位置,这里我们不能使用bindchange来校正,因为bindchange在切换时手指释放的时候就调用了,我们这里使用bindanimationfinish回调来校正(动画结束时会触发 animationfinish 事件,event.detail 同上)
最终:展示如下
在小程序开发文档中明确说明了最好不要频繁调用setData,我们最后这种方式就会频繁的调用,所以这里其实只是提供这种思路,但是工程中并不建议这么使用
小程序开发者文档
SwiperTab
下图是小程序 小米Lite 的 Tab 切换效果:切换 Page 时,Tab 下方的指示器(红色横条)是没有滚动效果而是直接闪现到下一个 Page 的,这也是市面上小程序常见的 Tab 切换效果。
原生端 TabLayout 常见的功能就是我们的目标效果,所以 目标效果 如下:
通过了解小程序组件及技术支持,选定通过 scroll-view 、swiper 、swiper-item 、movable-area 、movable-view 配合 插槽 和 抽象节点 来实现自定义组件 tab-layout 。
具体如下图所示 :
主要实现(点击跳转查看源码)
1.复制 tab-layout 组件到项目中 (点击跳转至源码 TabLayout 目录)
4.在布局文件中使用 TabLayout 组件,并通过抽象节点 generic:item-tab 和 generic:item-page 分别与自定义的 Tab 和 Page 绑定
5.使用自定义属性 indexAreaHeight 为 Index 及其活动区域设置高度
6.使用自定义属性 tabList 设置数据源,根据数据源将自动生成对应数量的 Tab 和 Page
7.按需选择可采用插槽 slot = "index" 或自定义属性 indexStyle 设置 Index 的样式
布局文件 index.wxml 中:
样式文件 index.wxss 中
布局文件 index.wxml 中
PS: 还有一个很重要的方法 onPageUpdata ,用于抽象节点 item-tab 和 item-page 通知父节点 tab-layout 刷新数据,在子控件中通过 this.triggerEvent("updata") 触发
可能出现问题:
1. 当 item-page 中存在竖直滚动的 scroll-view 时出现滑动冲突该如何解决?
在 item-page 组件 attached 方法中按需为 scroll-view 设置固定高度或占满屏幕剩余位置 (点击跳转查看参考写法)
2.当 item-page 或 item-tab 中调用 this.setData ( ) 之后,发现自定义属性 item 获取值为 null ?
出现该种情况,应在 this.setData ( ) 之后,执行 this.triggerEvent("updata") 触发 tab-layout 的 onPageUpdata 方法重新得到 item 值
3.如何实现 " 懒加载 " ,即当 Tab 首次被选中时,才进行对应 Page 的数据加载?
为自定义组件 item-page 设置一个懒加载标志位暂定为 isLoadData ,通过订阅自定义属性 currentIndex ,在 currentIndex 属性变化或组件进行到 attached 生命周期时,通过判断 isLoadData 和 currentIndex 是否与 position 相等来进行数据加载并调整标志位 (点击跳转查看参考写法)
在小程序越来越普及的现状下,如何使得小程序能给用户带来更完善的显示效果和使用体验,是每一个开发者都应该力尽其责的事。鉴于本人当前对小程序和网页端的熟悉程度,该组件或许还存在很多瑕疵,如有更好的见解或建议,欢迎留言。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)