在 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,让项目看起来更加合理。