react路由笔记
一、react路由(v5版本)
1. 什么是路由(前端)?
- 一个路由就算一个映射关系(key: value)
- key为路径,value为组件
2. 前端路由的工作原理
根据浏览器历史记录:history(BOM)
3. 路由的基本使用(react-router-dom)
3.1 react-router
:(有三种库)
-
- web (react-router-dom)
-
- react-native
-
- any
3.2 react-router-dom
的api(版本5/v5)
安装
npm i react-router-dom@5
内置组件
1. <BrowserRouter>
2. <HashRouter>
3. <Route>
4. <Redirect>
5. <Link>
6. <NavLink>
7. <Switch>
其他
- history 对象
- match 对象
- withRouter 函数
3.3 基本使用
App.js中
import { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
export default class App extends Component {
render() {
return {
<div>
<header>
{/* 编写路由链接 */}
<Link to="/home">首页</Link>
<Link to="/about">关于</Link>
</header>
<main>
{/* 注册路由 */}
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
</main>
</div>
}
}
}
index.js中
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, HashRouter } from 'react-router-dom'
import App from './App'
ReactDOM.render(
{/* history路由 */}
<BrowserRouter>
<App />
</BrowserRouter>
{/* hash路由 */}
<HashRouter></HashRouter>
, document.querySelect('#root'))
3.4 路由组件与一般组件
一般组件的props信息需要通过父组件传递,而路由组件的props信息是路由信息,不需要传递。
3.5 NavLink的使用
NavLink
的基本使用
匹配上的路由会默认加上active
这个类名
<NavLink to="/home">首页</NavLink>
<NavLink to="/about">关于</NavLink>
通过activeClassName
可以自定义选中的类名
<NavLink to="/home" activeClassName="header-active">首页</NavLink>
<NavLink to="/about" activeClassName="header-active">关于</NavLink>
- 对
NavLink
的封装
组件的使用:
{/* 「首页」标题:组件标签标签体内容(特殊的标签属性,组件内可以通过this.props.children获取) */}
<MyNavLink to="/home">首页</MyNavLink>
<MyNavLink to="/about">关于</MyNavLink>
组件的封装:
{/* 一组props */}
<NavLink to={to} activeClassName="header-active">首页</NavLink>
{/* 多组props */}
<NavLink {...this.props} activeClassName="header-active"/>
3.6 Switch的使用
Switch
:当匹配到第一个路由的时候就停止
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
<Route path="/about" component={Demo} />
</Switch>
3.7 路由的模糊匹配与精准匹配
模糊匹配:
<header>
<NavLink to="/about/a/b">关于</NavLink>
</header>
<main>
<Switch>
<Route path="/about" component={About} />
</Switch>
</main>
精准匹配:exact={true}
<Route exact={true} path="/about" component={About} />
3.8 Redirect的使用
Redirect(重定向):谁都匹配不上,就走Redirect
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
<Redirect to="/about" />
</Switch>
3.9 嵌套路由
嵌套路由要写完整路径
<div>
<NavLink to="/home/news">News</NavLink>
<NavLink to="/home/message">Message</NavLink>
</div>
<div>
<Switch>
<Route path="/home/news" component={News} />
<Route path="/home/message" component={Message} />
</Switch>
</div>
3.10 路由组件传参
1. 向路由组件传递params
参数
传递的参数:
<NavLink to={`/home/news/${title}/${page}`}>News</NavLink>
<Route path="/home/news/:title/:page" component={News} />
News组件可以通过this.props.match.params
获取到params
参数
2. 向路由组件传递search(query)
参数(显式传参)
使用:
<NavLink to={`/home/news?title=${title}&page=${page}`}>News</NavLink>
{/* search参数无需声明接收,正常注册路由即可 */}
<Route path="/home/news" component={News} />
接收:
接收到的search参数是urlencoded编码的字符串,需要借助querystring解析
key=value&key=value => urlencoded编码
安装query-string
npm i query-string
import qs from 'query-string'
qs.parse(this.props.location.search)
3. 向路由组件传递state
参数(隐式传参)
使用:
<NavLink to={{pathname: '/home/news', state: { title, page }}}>News</NavLink>
{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/news" component={News} />
接收:
通过this.props.location.state
接收,BrowserRouter
刷新参数不丢失,HashRouter
刷新参数丢失
3.11 push与replace模式
- push:会留下痕迹,可以通过回退键,回到上一页
- replace:不会留下痕迹,不能回到上一页
3.12 编程式路由导航
// 路由跳转
this.props.history.replace('/xxx', [state])
this.props.history.replace('/xxx', { id, title })
this.props.history.push('/xxx', [state])
this.props.history.push('/xxx', { id, title })
// 路由前进
this.props.history.goForward()
// 路由后退
this.props.history.goBack()
// 与vue中的go类似,传入number,正数表示前进,负数表示后退
this.props.history.go(number)
3.13 withRouter的使用
在一般组件内,不能像路由组件一样获取到路由信息,需要在组件上包裹一个withRouter
。withRouter
可以加工一般组件,让一般组件具备路由组件所特有的api,withRouter
的返回值是一个新组件。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
class App extends Component {
handleClick = () => {
console.log(this.props)
}
render() {
return (
<div onClick={this.handleClick}>关于</div>
)
}
}
export default withRouter(App)