最近小程序有一個新的需求,那就是對底部的TabBar進行各種的大小顏色等控制,沒辦法,默認的TabBar已經不夠打了,只能查文檔看看怎么自定義,果然是可以自定義的,小程序文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html
而且,文檔還貼心的給出了示例代碼,https://developers.weixin.qq.com/s/jiSARvmF7i55 ,點擊就可以用微信的開發者工具打開,nice!原來是在src目錄下新增一個custom-tab-bar的文件夾,同時在全局的配置文件中配置一下就可以了,哦呦,還挺簡單的嘛,可是心里總感覺很虛,因為以我之前開發時對Taro尿性的了解,保不齊就出點什么小毛病
對示例着照貓畫虎,總算是跑起來了,底部的tabbar也顯示出來了,但是果然發現問題了!在頁面DidShow時用Taro無法拿到TabBar的示例,進而無法刷新TabBar,切換TabBar時,顏色不會跟着改變,或者改變的是錯的!
開始網上大量查找解決辦法,https://www.jianshu.com/p/ec016dec7f9c ,最后借鑒了這篇文章的做法把問題解決了,我是通過Redux對tab的index狀態進行管理,從而使得切換正常的,但是第一次切換的時候,仍然有一點閃爍,不過只能先忍了,下班了,如果有人看的話,有時間把代碼整理整理貼上來,嘿嘿溜了溜了~
----------------------------------------------------------------------------------------------------------------------------------------------------
我來整理啦!
首先是主要結構:
- src
- custom-tab-bar
- index.jsx
- index.scss
- reducer
- index.js
- tabbar.js
- store
- index.js
- pages
- index
- index.jsx
- me
- index.jsx
- app.config.js
代碼:
1. src/custom-tab-bar/index.jsx
tabbar的主要文件,這里基本和小程序文檔給的示例一致,主要區別在於引入的狀態管理Redux,代碼上區別在最后export的時候有一個connect寫法。然后還要注意這里使用的是CoverView和CoverImage,這樣Tabbar基本一直在最上方,就算打開手機的調試模式,vconsole那個按鈕都會被蓋住。。。,這里有需要的可以替換成View和Image,靈活控制層級~
1 import React, {Component} from 'react' 2 import Taro from '@tarojs/taro' 3 import {CoverView, CoverImage} from '@tarojs/components' 4 5 import {connect} from 'react-redux' 6 7 import './index.scss' 8 9 class CustomTabBar extends Component { 10 tabInfo = { 11 color: '#7A7E83', 12 selectedColor: '#149EFF', 13 list: [ 14 { 15 pagePath: '/pages/index/index', 16 text: '首頁', 17 iconPath: '../asset/common/nav_index_normal.png', 18 selectedIconPath: '../asset/common/nav_index_selected.png', 19 }, 20 { 21 pagePath: '/pages/me/index', 22 text: '我的', 23 iconPath: '../asset/common/nav_my_normal.png', 24 selectedIconPath: '../asset/common/nav_my_selected.png', 25 }, 26 ], 27 } 28 29 switchTab = (e) => { 30 const data = e.currentTarget.dataset 31 Taro.switchTab({ 32 url: data.path, 33 }) 34 } 35 36 render() { 37 console.log('render', this.props.tabbar) 38 const activeTab = this.props.tabbar.index 39 return ( 40 <CoverView class="tab-bar"> 41 <CoverView class="tab-bar-border"></CoverView> 42 {this.tabInfo.list.map((item, index) => ( 43 <CoverView 44 class="tab-bar-item" 45 data-path={item.pagePath} 46 data-index={index} 47 onClick={(e) => this.switchTab(e)} 48 key={item.text} 49 > 50 <CoverImage 51 src={activeTab === index ? item.selectedIconPath : item.iconPath} 52 ></CoverImage> 53 <CoverView 54 style={`color: ${ 55 activeTab === index 56 ? this.tabInfo.selectedColor 57 : this.tabInfo.color 58 }`} 59 > 60 {item.text} 61 </CoverView> 62 </CoverView> 63 ))} 64 </CoverView> 65 ) 66 } 67 } 68 69 export default connect(({tabbar}) => ({ 70 tabbar, 71 }))(CustomTabBar)
2. src/custom-tab-bar/index.scss
tabbar的樣式,可以根據需求自定義哦~
.tab-bar { position: fixed; bottom: 0; left: 0; right: 0; height: 54Px; background: white; display: flex; padding-bottom: env(safe-area-inset-bottom); } .tab-bar-border { background-color: #F3F4F9; position: absolute; left: 0; top: 0; width: 100%; height: 1Px; transform: scaleY(0.5); } .tab-bar-item { flex: 1; text-align: center; display: flex; justify-content: center; align-items: center; flex-direction: column; } .tab-bar-item cover-image { width: 33Px; height: 33Px; } .tab-bar-item cover-view { font-size: 11Px; }
3. src/reducer/index.js
Redux的相關文件,主要是對當前的index進行一個全局的管理,以便在改變時讓tabbar刷新,因為我也是現學現賣就不多說明了,大家可以去Redux的官網看使用方法或者去這里Taro文檔
import {combineReducers} from 'redux'
import tabbar from './tabbar'
export default combineReducers({
tabbar,
})
4. src/reducer/tabbar.js
Redux的相關文件
const SETACTIVETAB = 'SETACTIVETAB' export const setActiveTab = (idx) => { return { type: SETACTIVETAB, meta: {idx}, } } const INITIAL_STATE = { index: 0, } export default function tabbarReducer(state = INITIAL_STATE, action) { switch (action.type) { case SETACTIVETAB: return { ...state, index: action.meta.idx, } default: return state } }
5. src/store/index.js
依然是Redux的相關文件
import {createStore, applyMiddleware, compose} from 'redux'
import thunkMiddleware from 'redux-thunk'
import rootReducer from '../reducers'
const composeEnhancers =
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
: compose
const middlewares = [thunkMiddleware]
// if (
// process.env.NODE_ENV === 'development' &&
// process.env.TARO_ENV !== 'quickapp'
// ) {
// middlewares.push(require('redux-logger').createLogger())
// }
const enhancer = composeEnhancers(
applyMiddleware(...middlewares)
// other store enhancers if any
)
export default function configStore() {
const store = createStore(rootReducer, enhancer)
return store
}
6. src/pages/index/index.js
差不多弄完了,接下來這兩個就是我們tabbar所要導航到的兩個頁面,在DidShow生命周期更新全局變量index,這樣Redux就會去刷新Tabbar的狀態
... import {connect} from 'react-redux' import {setActiveTab} from '../../reducers/tabbar' class Index extends Component { ... componentDidShow() { this.props.dispatch(setActiveTab(0)) } ... render() { ... } } export default connect()(Index)
7. src/pages/me/index.js
... import {connect} from 'react-redux' import {setActiveTab} from '../../reducers/tabbar' class Me extends Component { ... componentDidShow() { this.props.dispatch(setActiveTab(1)) } ... render() { ... } } export default connect()(Me)
8. src/app.config.js
偶對,別忘了全局配置文件中的改動,OK,完事兒
export default { ... tabBar: { custom: true, backgroundColor: '#fff', selectedColor: '#149EFF', list: [ { pagePath: 'pages/index/index', text: '首頁', iconPath: 'asset/common/nav_index_normal.png', selectedIconPath: 'asset/common/nav_index_selected.png', }, { pagePath: 'pages/me/index', text: '我的', iconPath: 'asset/common/nav_my_normal.png', selectedIconPath: 'asset/common/nav_my_selected.png', }, ], }, usingComponents: {}, }
總結一下,主要坑的點在於微信原生可以在對應導航的頁面中拿到Tabbar的實例,來setData
this.getTabBar().setData({ selected: 1 })
可是Taro中你得這么干
this.$scope.getTabBar().$component.setState({ ... })
但是你卻發現

心里一頓mmp之后還是抱有一絲希望的使用getCurrentInstance().page,並把它的返回結果打印出來,但是怎么找也找不到實例的setState或者可以改變狀態的可行辦法(好像里面有個setData,但是不管用?),然后就¥%&¥&……*…………*¥
啊好了,好消息總算是可以解決這個問題了,不得不說小程序坑是真的多,Taro也是,我好苦啊~~嗚嗚,有時間再寫一些其他的坑,好了,該休息了,晚安了
如果這篇文章幫到你,記得留言讓我知道哦,讓我知道我不是一個人,如果有更好的解決辦法或者錯誤也請不吝賜教,溜了溜了
