概要
微信小程序自定义底部导航栏,原生实现,不包含其他任何第三方组件,比较干净,开箱即用
效果预览:
功能
- 可自定义底部导航栏列表样式
- 可自定义每个菜单的默认、激活后的图标和文字样式
- 可自定义是否添加中间的大图标菜单,当然也可自定义大图标的默认与激活样式
- 可自定义激活动画,默认这个心跳过渡动画
- 可获取到底部导航栏高度,存在app全局变量中,其他页面有特殊需求需要动态计算页面高度时可能需要用到此属性
- 解决点击导航菜单时,激活的菜单貌似并不同步的问题
- 底部根据是否有安全距离自动调整
源码
不废话,直接贴上完整源码
js
const app = getApp()
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
selected: 0, // 激活的tab
// tabber列表,与app.json一致
color: "#666666",
selectedColor: "#ff0000",
backgroundColor: "#ffffff",
// 注: list中的pagePath需要加'/'开头,否则在switchTab跳转url时会自带/src/pages开头导致路径错误
list: [{
"pagePath": "/src/pages/home/home",
"icon": "./images/home.png",
"iconActive": "./images/home-a.png",
"text": "首页",
}, {
"pagePath": "/src/pages/monitor/monitor",
"icon": "./images/relic.png",
"iconActive": "./images/relic-a.png",
"text": "文物监测"
}, {
"pagePath": "/src/pages/map/map",
"icon": "./images/map.png",
"iconActive": "./images/map.png",
"center": true, // 中间大图标的参数,true时就会变大,默认非大图标
}, {
"pagePath": "/src/pages/news/news",
"icon": "./images/hot.png",
"iconActive": "./images/hot-a.png",
"text": "文博资讯"
}, {
"pagePath": "/src/pages/mine/mine",
"icon": "./images/mine.png",
"iconActive": "./images/mine-a.png",
"text": "我的"
}],
tabbarHeight: 0
},
lifetimes: {
attached: function () {
// 获取tab栏高度
const query = wx.createSelectorQuery().in(this)
query.select('#tabbar').boundingClientRect((res) => {
// console.log('tab栏dom', res);
this.setData({
tabbarHeight: res.height
})
// 将tab栏高度设置进全局数据
app.globalData.tabbarHeight = res.height
}).exec()
/**
* 将初始化tabbar栏方法存入全局
* @param {*} that 传入当前tab页面的this实例
* @param {*} index 传入当前tab页面的索引
* 若无该方法,会导致点击tab时激活的tab顺序错乱!
* 例如在home首页onShow的生命周期钩子中,getApp().globalData.initTabbar(this, 0)
*/
app.globalData.initTabbar = (that, index) => {
if (typeof that.getTabBar === 'function' && that.getTabBar()) {
that.getTabBar().setData({
selected: index
})
}
}
}
},
/**
* 组件的方法列表
*/
methods: {
switchTab(e) {
// bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡
const {
index,
url
} = e.currentTarget.dataset
if (this.data.selected !== index) {
this.setData({
selected: index
})
wx.switchTab({
url: url,
})
}
}
}
})
wxml
<view class="tabbar" style="background-color: {{backgroundColor}};" id="tabbar">
<view class="{{'tab'}} {{selected == index ? 'beat' : ''}}" wx:for="{{list}}" wx:key="item" catchtap="switchTab" data-index="{{index}}" data-url="{{item.pagePath}}">
<view class="{{'tab-icon'}} {{item.center ? 'tab-icon-center' : ''}}" style="background-color: {{backgroundColor}};">
<image style="width:100%;height:100%;" src="{{selected == index ? item.iconActive : item.icon}}" mode="" />
</view>
<view style="font-size:24rpx;color:{{selected == index ? selectedColor : color}}">
{{item.text}}
</view>
</view>
</view>
wxss
.tabbar {
position: fixed;
bottom: 0;
width: 100%;
height: 120rpx;
background: rgba(255, 255, 255, 1);
box-shadow: 0 2px 16px rgba(184, 184, 210, 0.5);
/* 利用ios新增的 env() 和 constant() 特性,自动计算底部安全距离 */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
display: flex;
justify-content: space-evenly;
}
.tab {
width: 100%;
height: 100%;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
}
.tab-icon {
width: 68rpx;
height: 68rpx;
}
.tab-icon-center {
width: 160rpx;
height: 160rpx;
position: absolute;
top: -24rpx;
padding: 12rpx;
box-sizing: border-box;
border-radius: 80rpx;
}
.beat {
animation: beat 0.8s both;
}
@keyframes beat {
0% {
transform: scale3d(1, 1, 1);
}
30% {
transform: scale3d(1.05, 0.95, 1);
}
40% {
transform: scale3d(0.85, 1.15, 1);
}
50% {
transform: scale3d(1.15, 0.85, 1);
}
65% {
transform: scale3d(0.95, 1.05, 1);
}
75% {
transform: scale3d(1.05, 0.95, 1);
}
100% {
transform: scale3d(1, 1, 1);
}
}
不要忘了在app.json文件中添加 tabBar 属性文章来源:https://www.toymoban.com/news/detail-732538.html
"tabBar": {
"custom": true,
"color": "#666666",
"selectedColor": "#ff0000",
"backgroundColor": "#000000",
"list": [
{
"pagePath": "src/pages/home/home",
"text": "首页"
},
{
"pagePath": "src/pages/monitor/monitor",
"text": "监测"
},
{
"pagePath": "src/pages/map/map",
"text": "地图"
},
{
"pagePath": "src/pages/news/news",
"text": "资讯"
},
{
"pagePath": "src/pages/mine/mine",
"text": "我的"
}
]
}
细节
- 注意上述js代码块中 initTabbar 方法,需要在每个tabbar页面使用
例如首页是home,那么就在home.js中的onShow生命周期钩子中,写上getApp().globalData.initTabbar(this, 0)即可,参数中的0就是该tabbar的索引位置,第一个页面就是0,第二个就是1,以此类推 - 注意页面路径问题,在代码块中有注释
- 注意这个custom-tab-bar组件要放在根目录哦
改进
有问题和改进建议还请在评论区留言,觉得代码还不错的话,还望点个赞让更多人看到哦文章来源地址https://www.toymoban.com/news/detail-732538.html
到了这里,关于微信小程序自定义底部导航栏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!