赞
踩
看一下演示效果
之前也做过一个类似的,tab(navigator) 栏,但是 tab 标签下面的小横线没有过渡效果,看起来会很生硬,而且不是和 swiper 联动,总体效果不尽人意,这是一个改进版
之前的 tab 栏切换效果演示,用来做学习的话还是很不错的,感兴趣的可以点这里跳转->旧版(学习版)地址
看一下代码吧,实现起来比较简单,也比较初级
.wxml
<!-- tab --> <view class="tit_box"> <view class='navbar' id="navbar"> <!-- 循环遍历导航栏 --> <!-- 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。 --> <block wx:for="{{tabs}}" wx:key="*this"> <view class="navbar-item" data-index='{{item.id}}' bindtap='onTabClick'> <view class="navbar-title {{item.isActive?'active':''}}">{{item.name}}</view> </view> </block> <!-- 导航栏下部的小横线 --> <view class="navbar-slider" style="left: {{sliderLeft}}px; width:50px; transition: all .5s;);" /> </view> </view> <!-- 内容区 swiper --> <swiper current="{{swiperCurrent}}" circular bindchange='swiperChange'> <swiper-item wx:for="{{tabs}}" wx:key="*this"> <view class="content">{{item.name}}</view> </swiper-item> </swiper>
.wxss( 这次没用less,感兴趣的同学可以自己改一下,样式啥的基本没啥特别难的 )
.tit_box { display: flex; } .navbar { display: flex; position: relative; flex: 1; z-index: 500; top: 0; width: 100%; background-color: #ececec; } .navbar .navbar-item { position: relative; display: block; flex: 1; padding: 13px 0; text-align: center; font-size: 0; } .navbar .navbar-title { display: inline-block; font-size: 15px; width: auto; } .active { color: #118ef5; } .navbar .navbar-slider { position: absolute; content: " "; left: 0; bottom: 0; width: 100rpx; height: 5rpx; background-color: #118ef5; } .content { background-color: rgb(0, 255, 85); height: 100%; text-align: center; }
.js
let itemWidth = 0; Page({ data: { // 每个tab位置下的小横线坐标,每次切换后的坐标记录在数组中 sliderOffsets: [], // tab下面的横线,偏左的距离 sliderLeft: 0, tabs: [ { id: 0, name: "TAB1", isActive: true }, { id: 1, name: "TAB2", isActive: false }, { id: 2, name: "TAB3", isActive: false } ], swiperCurrent: 0 }, onLoad: function (options) { this.clueOffset(); }, clueOffset() { // 保留外部的this var that = this; //声明节点查询的方法 wx.createSelectorQuery().select('#navbar') .boundingClientRect(function (rect) { // Math.ceil向上取整,itemWidth(每个tab的宽度--距离) = tab栏宽度(375px) / tab数量(3) itemWidth = Math.ceil(rect.width / that.data.tabs.length); // 定义一个空数组,接收每个tab位置下的小横线坐标 let tempArr = []; // 几个tab循环几次,把坐标填进去 for (let i in that.data.tabs) { // -50是因为下面的小横线宽度是50 tempArr.push((itemWidth * i) + ((itemWidth - 50) / 2)); } that.setData({ sliderOffsets: tempArr, sliderLeft: tempArr[0] }); }).exec(); }, /** * tabItme点击事件 */ onTabClick(event) { // 获取点击的tabItme序号 let { index } = event.currentTarget.dataset; this.forEachChange(index) this.setData({ sliderLeft: this.data.sliderOffsets[index], swiperCurrent: index }) }, /** * swiper-item切换时执行的函数 */ swiperChange: function (e) { // 获取当前swiper-item的序号 const { current } = e.detail this.forEachChange(current) this.setData({ sliderLeft: this.data.sliderOffsets[current], swiperCurrent: current }) }, /** * 提取公共部分,封装成函数(tab标签选中的颜色) */ forEachChange: function (index) { const { tabs } = this.data; tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false) this.setData({ tabs }) } })
代码gitee地址:https://gitee.com/chenminghuisir/wechat-applet-component
也可以点击这里直接跳转
代码保存在仓库,PrincessConnect文件里
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。