概要
微信小程序自定義底部導(dǎo)航欄,原生實(shí)現(xiàn),不包含其他任何第三方組件,比較干凈,開箱即用
效果預(yù)覽:
功能
- 可自定義底部導(dǎo)航欄列表樣式
- 可自定義每個(gè)菜單的默認(rèn)、激活后的圖標(biāo)和文字樣式
- 可自定義是否添加中間的大圖標(biāo)菜單,當(dāng)然也可自定義大圖標(biāo)的默認(rèn)與激活樣式
- 可自定義激活動(dòng)畫,默認(rèn)這個(gè)心跳過(guò)渡動(dòng)畫
- 可獲取到底部導(dǎo)航欄高度,存在app全局變量中,其他頁(yè)面有特殊需求需要?jiǎng)討B(tài)計(jì)算頁(yè)面高度時(shí)可能需要用到此屬性
- 解決點(diǎn)擊導(dǎo)航菜單時(shí),激活的菜單貌似并不同步的問(wèn)題
- 底部根據(jù)是否有安全距離自動(dòng)調(diào)整
源碼
不廢話,直接貼上完整源碼
js
const app = getApp()
Component({
/**
* 組件的屬性列表
*/
properties: {
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
selected: 0, // 激活的tab
// tabber列表,與app.json一致
color: "#666666",
selectedColor: "#ff0000",
backgroundColor: "#ffffff",
// 注: list中的pagePath需要加'/'開頭,否則在switchTab跳轉(zhuǎn)url時(shí)會(huì)自帶/src/pages開頭導(dǎo)致路徑錯(cuò)誤
list: [{
"pagePath": "/src/pages/home/home",
"icon": "./images/home.png",
"iconActive": "./images/home-a.png",
"text": "首頁(yè)",
}, {
"pagePath": "/src/pages/monitor/monitor",
"icon": "./images/relic.png",
"iconActive": "./images/relic-a.png",
"text": "文物監(jiān)測(cè)"
}, {
"pagePath": "/src/pages/map/map",
"icon": "./images/map.png",
"iconActive": "./images/map.png",
"center": true, // 中間大圖標(biāo)的參數(shù),true時(shí)就會(huì)變大,默認(rèn)非大圖標(biāo)
}, {
"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欄高度設(shè)置進(jìn)全局?jǐn)?shù)據(jù)
app.globalData.tabbarHeight = res.height
}).exec()
/**
* 將初始化tabbar欄方法存入全局
* @param {*} that 傳入當(dāng)前tab頁(yè)面的this實(shí)例
* @param {*} index 傳入當(dāng)前tab頁(yè)面的索引
* 若無(wú)該方法,會(huì)導(dǎo)致點(diǎn)擊tab時(shí)激活的tab順序錯(cuò)亂!
* 例如在home首頁(yè)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事件綁定不會(huì)阻止冒泡事件向上冒泡,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() 特性,自動(dòng)計(jì)算底部安全距離 */
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 屬性文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-732538.html
"tabBar": {
"custom": true,
"color": "#666666",
"selectedColor": "#ff0000",
"backgroundColor": "#000000",
"list": [
{
"pagePath": "src/pages/home/home",
"text": "首頁(yè)"
},
{
"pagePath": "src/pages/monitor/monitor",
"text": "監(jiān)測(cè)"
},
{
"pagePath": "src/pages/map/map",
"text": "地圖"
},
{
"pagePath": "src/pages/news/news",
"text": "資訊"
},
{
"pagePath": "src/pages/mine/mine",
"text": "我的"
}
]
}
細(xì)節(jié)
- 注意上述js代碼塊中 initTabbar 方法,需要在每個(gè)tabbar頁(yè)面使用
例如首頁(yè)是home,那么就在home.js中的onShow生命周期鉤子中,寫上getApp().globalData.initTabbar(this, 0)即可,參數(shù)中的0就是該tabbar的索引位置,第一個(gè)頁(yè)面就是0,第二個(gè)就是1,以此類推 - 注意頁(yè)面路徑問(wèn)題,在代碼塊中有注釋
- 注意這個(gè)custom-tab-bar組件要放在根目錄哦
改進(jìn)
有問(wèn)題和改進(jìn)建議還請(qǐng)?jiān)谠u(píng)論區(qū)留言,覺得代碼還不錯(cuò)的話,還望點(diǎn)個(gè)贊讓更多人看到哦文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-732538.html
到了這里,關(guān)于微信小程序自定義底部導(dǎo)航欄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!