最近用了几次react-router感觉对其使用还不够熟练,所以看着官方文档复习了一下,顺便做个笔记。
因为webpack懒得搭环境了 所以直接上parcel 0 配置 很好用 但是正式开发我还是喜欢webpack 因为足够灵活
先上demo的 github链接
这是官方文档链接
匹配原理
Route 组件匹配采用从上到下依次匹配,直到最后一个路由或者无可匹配的路由为止。若想只匹配一个路由,请使用Switch组件
基本使用
选择Router:
react-router 提供了五种router供选择,但前端常用到的就三种,具体区别 见文档, 这次选择 BrowserRouter
Router 需要传递history
BrowserRouter (官方推荐) 使用时需要服务器配合配置,若使用webpack开发需打开historyApiFallback选项
HashRouter url中有一个#号
开始配置
初始配置
现在有三个页面 home , book 和 book的子页面kongfu,如下
<li><Link to='/'>home</Link></li> <li><Link to='/movie'>movie</Link></li> <li><Link to='/movie/kongfu'>kongfu</Link></li> <Route path='/' component={Home} /> <Route path='/movie' component={Movie} /> <Route path='/movie/kongfu' component={KongFu} />
每一个被匹配到的路由均渲染了对应的组件,效果图如下:
step1.gif
若我们想只匹配一个组件怎么办?往下看。
使用Switch组件
修改上面的路由部分代码,添加Switch组件
<Switch> <Route path='/' component={Home} /> <Route path='/movie' component={Movie} /> <Route path='/movie/kongfu' component={KongFu} /></Switch>
无论跳转到任何一个路由都只会匹配第一个路由home。效果图如下:
step2.gif
但是我们并不想要这样的结果,有两个办法可以解决
把最精确的路由放在最前面
Route组件添加exact属性
如下
// 第一种方法<Switch> <Route path='/movie/kongfu' component={KongFu} /> <Route path='/movie' component={Movie} /> <Route path='/' component={Home} /></Switch>// 第二种方法<Switch> <Route exact path='/' component={Home} /> <Route exact path='/movie' component={Movie} /> <Route exact path='/movie/kongfu' component={KongFu} /></Switch>
效果图如下:
step3.gif
布局
单个布局
我们日常使用过程中经常会有导航栏或者侧边栏的需求,如下。
header作为导航栏部分, main作为匹配路由的部分
<header style={{backgroundColor:'#b8cca6'}}> <h1>This is header</h1> </header> <main style={{backgroundColor:'#26899e'}}> <Switch> <Route exact path='/' component={Home} /> <Route exact path='/movie' component={Movie} /> <Route exact path='/book' component={Book} /> </Switch> </main>
为了效果,明显对header以及main部分加了背景色,如下图:
step4.gif
如果我们有多个布局怎么办? 比如常见的还有登录布局,往下看。
多个布局
为实现多个布局我们将多个布局提取成多个组件
/***** BasicLayout.jsx *****/<div> <h1>BasicLayout!!</h1> <Route exact path='/' component={Home} /> <Route exact path='/movie' component={Movie} /> <Route exact path='/book' component={Book} /></div> /***** LoginLayout.jsx *****/<div> <h1>LoginLayout!!</h1> <form action=""> username: <input type="text" placeholder='please input username'/> <br /> password: <input type="password" placeholder='please input password'/> </form></div>/***** App.jsx *****/ // 注意 有子路由的Route不要加exact不然会匹配不到子路由,<Switch> <Route path='/login' component={LoginLayout} /> <Route path='/' component={BasicLayout} /></Switch>
如下图:
step5.gif
登录验证
既然有登录布局 自然就需要有登录验证
官方推荐的做法是自己实现一个AuthRoute,如下
const AuthRoute = (props) => { const { component:Component, ...rest } = props; // parcel 默认不支持rest参数, 需添加babel-plugin-transform-object-rest-spread 并添加到.babelrc文件中 // const rest = {}; // for (const _key in props) { // if(_key !== 'component') { // rest[_key] = props[_key] // } // } return (<Route {...rest} render={(props) => ( islogin()? (<Component {...props} />) : (<Redirect to='/login' />) )} />) }
此处有两个小坑,
parcel默认不支持rest参数,具体看上面代码注释。
Route组件的 component 和 render 都会在路径匹配时渲染组件,但component优先级较高,若两个属性同时出现render会被忽略。
下面看下效果:
首先是未登录状态 任何路由都无法进入 只能停留在login页
step6.gif
下面是登陆后的效果,任何路由都可以访问,登出后之能访问login页
step7.gif
编程式导航
既然有了登录验证 那我们总不能让用户自己点其他路由跳转到首页吧! 下面就来使用withRouter 在登陆成功后让代码手动跳转到首页
const { history } = this.props history.push('/');
被Route包裹的组件都会在props拥有history,match,location对象,使用hisory对象的push方法即可进行手动跳转。
效果如下图:
step8.gif
withRouter
若在Route组件之外想要访问 history,match,location对象并做一些操作呢?
这时候withRouter就排上用场了,
每次路由发生变化时Router包裹的组件会被重新渲染,
withRouter包裹的组件就可访问到路由信息对象,就可以响应路由变化
我们改造一下导航部分 将其封装成一个Nav组件, 在export时用withRouter包裹。
import { withRouter, Link } from 'react-router-dom'; class Nav extends Component { render() { const activeStyle = { backgroundColor: '#00a74a' } const path = this.props.location.pathname; console.log('test', this.props) return ( <ul> <li><Link to='/login' style={path === '/login'?activeStyle:{}} >login</Link ></li> <li><Link to='/' style={path === '/'?activeStyle:{}} >home</Link ></li> <li><Link to='/movie' style={path === '/movie'?activeStyle:{}}>movie</Link ></li> <li><Link to='/book' style={path === '/book'?activeStyle:{}}>book</Link ></li> </ul> ) } } export default withRouter(Nav);
效果如下图:
step9.gif
以上就是一些react-router v4的一些基本使用。若有错误欢迎指出!
Tips: 注意看文中的Route 和Router 就差一个字母 不要看花了眼哦
作者:Lumiance
链接:https://www.jianshu.com/p/bb05ac984dab
共同学习,写下你的评论
评论加载中...
作者其他优质文章