多圖警告!!!
最近在工作中遇到這樣一個需求:微信小程序底部的Tab需要通過判斷登錄人的角色動態進行改變,想要實現這個功能依靠小程序原生的Tabbar是不可能實現的了,所以研究了一下自定義Tab,這里記錄一下
微信小程序的Tab
想要寫自定義Tab首先要知道原生Tab是什么,新建一個微信小程序運行起來,默認是這個樣子的

簡單修改一下小程序自帶的logs頁面,大概是這個樣子(通過兩個按鈕模擬角色,就不寫登錄了)

目前想要在兩個頁面之前來回切換只能通過修改app.json中pages的順序才能實現,所以我們需要底部的Tab,官方文檔 中對Tab的使用有詳細介紹,我這里選擇在app.json中添加tabBar實現:
// app.json文件中pages同級的位置增加tabBar來配置底部Tab
"tabBar": {
// 文字默認顏色
"color": "#5F5F5F",
// 文字選中顏色
"selectedColor": "#027FF5",
// Tab背景顏色
"backgroundColor": "#F7F7F7",
// Tab列表
"list": [{
// Tab默認圖標
"iconPath": "/images/footer-01.png",
// Tab選中圖標
"selectedIconPath": "/images/footer-01-h.png",
// Tab跳轉的目標路徑,參考上面的pages屬性即可
"pagePath": "pages/index/index",
// Tab底部顯示的文字
"text": "首頁"
}, {
"iconPath": "/images/footer-03.png",
"selectedIconPath": "/images/footer-03-h.png",
"pagePath": "pages/logs/logs",
"text": "測試頁"
}]
},

這樣一來就可以通過點擊底部Tab來切換顯示頁面了,這就是微信小程序的Tab
自定義Tab
針對自定義Tab 官方文檔 中也有詳細說明,需要在根目錄創建一個組件(Component),名稱要固定寫好:

然后在app.json中找到之前添加的tabBar屬性,在他下面添加這樣一個屬性:

之后就會發現底部Tab已經變成了剛剛創建的組件,接下來就開始繪制Tab頁

官方建議繪制Tab時最好使用cover-view + cover-image標簽搭配flex布局,保證Tab層級較高

這樣一來自定義的Tab就已經成功了一半了,接下來就要結合JS讓他稱為真正的Tab,為了讓自定義Tab使用起來更順手,這里按照app.json的tab格式將配置粘貼到JS文件中,然后修改下wxml讓頁面數據變成動態的,這樣Tab列表的功能就完成了!

然后要實現Tab點擊切換頁面的核心功能,我們在每個Tab上添加一個點擊事件,然后將需要跳轉的目標路徑傳入到跳轉方法中,然后頁面跳轉就實現了

接下來實現的是頁面Tab高亮,之前在wxml中已經寫了根據index判斷的條件,接下來只需要在訪問頁面時記錄tabIndex就沒問題了

這樣乍一看的確實現了高亮的效果,但是當仔細觀察后就會發現,只有在第二次點擊的時候高亮才會同步過去,Tab更新不及時,所以這里不能采取這種方法,應該讓頁面來決定那個Tab應該高亮,將switchTab中的setData移除掉,分別在首頁和測試頁添加更新高亮的代碼:

OK!這樣自定義Tab就可以正常使用了!
動態Tab實現
准備工作做的差不多了,現在開始實現動態Tab,鑒於在之前設置高亮的時候發現了Tab中數據更新不及時的問題,以及每個Page的onShow中都會調用重復代碼,這里決定書寫一個服務將Tab常用操作都封裝進去,在utils文件夾下新建tab-service.js,跟Tab相關的東西都放到這個下面:
// Tab頁的data
let tabData = {
tabIndex: 0,
tabBar: {
custom: true,
color: "#5F5F5F",
selectedColor: "#027FF5",
backgroundColor: "#F7F7F7",
list: [{
iconPath: "/images/footer-01.png",
selectedIconPath: "/images/footer-01-h.png",
pagePath: "pages/index/index",
text: "首頁"
}, {
iconPath: "/images/footer-03.png",
selectedIconPath: "/images/footer-03-h.png",
pagePath: "pages/logs/logs",
text: "測試頁"
}]
}
}
// 更新角色
const updateRole = (that, role) => {
tabData.tabBar.list[0].text = role + "首頁";
updateTab(that);
}
// 更新底部高亮
const updateIndex = (that, index) => {
tabData.tabIndex = index;
updateTab(that);
}
// 更新Tab狀態
const updateTab = (that) => {
if (typeof that.getTabBar === 'function' && that.getTabBar()) {
that.getTabBar().setData(tabData);
}
}
// 將可調用的方法拋出讓外面調用
module.exports = {
updateRole, updateTab, updateIndex
}
之前說了那么多,這里動態Tab細節就不多說了,點擊下載代碼 看看就懂了
