在 react-router 環境下使用 antd-mobile tabbar
- 2020 年 1 月 4 日
- 筆記
本文闡述了如何在一個使用了 react-router 的 react 項目中合理的使用 antd-mobile tabbar 功能。在 antd-mobile 官方的例子中可以看到,只需要將不同的組件放置到每個 TabBar.Item
裡面就可以了,這樣就可以實現簡單的切換效果,但是存在幾個問題。
一個是切換過程中,路由是不會跟著切換的。比如我們想分享一個地址,當其他人打開這個地址時自動就跳轉到第二個 tab 上。如果按上面的方法做是無法實現的。
另外一個問題是這樣的設計不太符合大型項目的框架設計,我們往往會製作一些 layouts,給不同的組件匹配不同的 layout。如果按上面介紹的方法做,也是不好實現的。
綜合以上兩點問題,再加上 Google 了一些資料後,寫下本文,以幫助更多遇到類似問題的人。
解決方案
首先定義四個路由分別指定不同的 component,要注意的是這四個路由都統一使用一個 layout,這也就解決了一些大型項目中分多種 layout 的問題。如下程式碼所示:
<Router history={browserHistory}> {/* MainLayout 中包含了 antd-mobile tabbar */} <Route path='/' component={MainLayout}> {/* 默認跳轉到 questions 頁面 */} <IndexRedirect to='/questions' /> <Route path='/questions' component={Questions} /> <Route path='/activities' component={Activities} /> <Route path='/videos' component={Videos} /> <Route path='/mine' component={Mine} /> </Route> </Router>
隨後我們看一下 mainLayout 的程式碼:
const MainLayout = ({children}) => { const pathname = children.props.location.pathname return ( <TabBar unselectedTintColor='#949494' tintColor='#33A3F4' barTintColor='white' > <TabBar.Item title='問答' key='questions' icon={<div className='questions-icon' />} selectedIcon={<div className='questions-selected-icon' />} selected={pathname === '/questions'} onPress={() => { browserHistory.push('/questions') }} > { pathname === '/questions' ? children : null } </TabBar.Item> <TabBar.Item title='活動' key='activities' icon={<div className='activities-icon' />} selectedIcon={<div className='activities-selected-icon' />} selected={pathname === '/activities'} onPress={() => { browserHistory.push('/activities') }} > { pathname === '/activities' ? children : null } </TabBar.Item> <TabBar.Item title='影片' key='videos' icon={<div className='videos-icon' />} selectedIcon={<div className='videos-selected-icon' />} selected={pathname === '/videos'} onPress={() => { browserHistory.push('/videos') }} > { pathname === '/videos' ? children : null } </TabBar.Item> <TabBar.Item title='我的' key='mine' icon={<div className='mine-icon' />} selectedIcon={<div className='mine-selected-icon' />} selected={pathname === '/mine'} onPress={() => { browserHistory.push('/mine') }} > { pathname === '/mine' ? children : null } </TabBar.Item> </TabBar> ) }
這裡重點的程式碼就是 pathname === '/questions' ? children : null
,根據當前路由判斷載入不同的 component,並且在點擊任何一個按鈕的時候,自動跳轉到指定的路由上。其中 selected 屬性也根據路由動態的變換樣式。路由傳遞給 mainLayout 是一個 children,這個 children 中就包含了組件的資訊,我們根據路由的不同載入即可。
總結
這樣處理後無論我們直接訪問 URL 還是點擊 tabbar 下面的任意按鈕,不但可以切換頁面,路由也會隨之變動。最重要的是我們套用了 layout,讓項目看起來更加合理。