React路由5版本
什么是路由?
一个路由就是一个映射关系(key:value).
以下代码用的都是router5
通过 npm install react-router-dom@5 下载
所有路由用到的东西都需要从react-router-dom中引入
import {BrowserRouter,Link,Route,NavLink,Redirect,withRouter} from 'react-router-dom'
1. 路由的基本使用
1.明确好界面的导航区,展示区2.导航区的a标签改为Ling标签<Link to='/xxx' > demo </Link>3.展示区写Route标签进行路由匹配<Route path='/xxx' component={Demo}/>4.<App> 最外侧包裹一个<BrowserRouter>或者<HashRouter><BrowserRouter>{/* 所有的路由调整都要BrowserRouter包裹, 直接在index中包裹, 一劳永逸*/}<App /></BrowserRouter>
2. 路由组件与一般组件
1.写法不同一般组件: <Demo/>路由组件: <Route path='/demo' component={Demo}/>2.存放位置不同一般组件: components路由组件: page
3.接收到的props不同一般组件: 给组件标签传递什么,就接收什么路由组件: 接受三个固定属性history:go: fn,goBack: fn,goForward: fn,push: fn push(path,state),replace: fn replace(path,state)location:pathname: '/about',search: '',state: undefinedmatch:params: {},path: '/about',url: '/about'
3.NavLink与封装NavLink
1.NavLink可以实现路由链接的高亮, 通过activeClassName指定样式名
<NavLink className='list-group-item' activeClassName='atguigu' {...this.props}></NavLink>2.标签体内容是一个特殊的标签属性3.通过this.props.children可以获取标签体内容
4.Switch的使用
1.通常情况下,path和component是一一对应的关系
2.Switch可以提高路由匹配效率(单一匹配) 找到匹配的路由就不往下继续查找了<Switch><Route path='/about' component={about}/><Route path='/home' component={home}/>
</Switch>
5.路由的严格匹配与模糊匹配
1.默认使用的是模糊匹配(输入的路径必须包含要匹配的路径,且顺序要一致)2.开启严格模式: <Route exact={true} /> 或exact3.严格匹配不要随便开启,需要再开, 有时候开启会导致无法继续匹配二级路由
6.Redirect的使用
1.一般写在所有路由注册的最下方, 当所有路由都无法匹配时, 跳转到Redirect指定的路由2.具体编码:<Switch><Route path='/home' component={home}/><Redirect to='/about'/></Switch>
7.嵌套路由
1.注册子路由时要写上父路由的path值
2.路由的匹配是按照注册路由的顺序进行的.编码:<MyNavLink to='/home/message'>message</MyNavLink><Route path='/home/message' component={message}></Route>
8.向路由组件传递参数
1.params传递参数
1.路由链接(携带参数): <Link to={`/home/message/detail/${id}/${title}`}>params传递数据</Link>2.注册路由(声明接收): <Route path='/home/message/detail/:id/:title' component={detail}/>3.接收参数: const { id,title } = this.props.match.params
2.search传递参数
1.路由链接(携带参数):
<Link to={`/home/message/detail/?id=${id}&title=${title}`}> search传递数据 </Link>2.注册路由(无需声明接收):
<Route path='/home/message/detail' component={detail}/>3.接收参数:
const { id, title } = qs.parse(this.props.location.search.slice(1))备注: 获取到的search是urlencoded编码字符串, 需要借助qs.parse()解析 (npm i qs)
3.state传递参数
1.路由链接(携带参数):
<Link to={{pathname='/home/message/detail',state:{id,title}}}> state传递参数 </Link>2.注册路由(无需声明接收):
<Route path='/home/message/detail' component={detail}/>3.接收参数:
const { id,title } = this.props.location.state || {}备注: 携带的参数不在地址栏体现,刷新页面数据不会丢失
9.编程式路由导航
借助this.props.history对象上的API对操作路由跳转,前进,后退
-this.props.history.push()
-this.props.history.replace()
-this.props.history.goBack()
-this.props.history.goForward()
-this.props.history.go()编码:
state = {id:119,title: '标题'
}// push和replace方法一个是王历史记录中追加, 一个是替换当前的记录. 用法是一样的clickParams = () => {
this.props.history.push(`/home/message/detail/${this.state.id}/${this.state.title}`)
}clickSearch = () => {
this.props.history.replace(`/home/message/detail?id=${this.state.id}&title=${this.state.id}`)
}clickState = () => {
this.props.history.replace('/home/message/detail',{id:this.state.id,title:this.state.title})
}
10.withRouter
以App组件为例, 声明一个App组件,导出的时候用withRouter包裹一下就行
class App ...
export default withRouter(App)withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
withRouter的返回值是一个新组件
11.BrowserRouter 和 HashRouter区别?
1.底层原理不一样:BrowserRouter使用的是H5的history API. 不兼容IE9及以下版本HashRouter使用的是URL的哈希值2.URL表现形式不一样browserRouter的路径中没有#HashRouter的路径中有#3.刷新后对路由state参数的影响BrowserRouter没有任何影响,因为state保存在history中HashRouter刷新后会导致路由state参数的丢失