原生微信小程序,navigate(导航栏)tab栏,tab栏与swiper结合,含过渡动画,初级
程序员文章站
2024-03-21 11:31:16
...
原生微信小程序,navigate(导航栏)tab栏,tab栏与swiper结合,含过渡动画,初级
看一下演示效果
之前也做过一个类似的,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文件里