注意:v6 版本相比 v5 版本有破坏性更新! v6 文档
步骤:
yarn add react-router-dom@5.3.0
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
const First = () => <p>页面一的页面内容</p>
const App = () => {
return (
<Router>
<div className="App">
<ul>
<li>
{/*
to属性:浏览器地址栏中的pathname(location.pathname)
*/}
<Link to="/first">页面一</Link>
</li>
</ul>
{/*
path属性:路由规则
component属性:展示的组件
Route 组件写在哪,渲染出来的组件就展示在哪
*/}
<Route path="/first" component={First}></Route>
</div>
</Router>
)
}
Router 组件:包裹整个应用,一个 React 应用只需要使用一次
两种常用 Router:HashRouter
和 BrowserRouter
HashRouter:使用 URL 的哈希值实现(
http://localhost:3000/#/first)
hashchange
事件来实现的(推荐)
BrowserRouter
:使用 H5 的 history.pushState() API 实现(
popstate
事件来实现的Link
组件:用于指定导航链接,会渲染成 a 标签
to
属性,将来会渲染成 a 标签的 href 属性<Link to="/first">页面一</Link>
// 渲染为:
<a href="/first">页面一</a>
除了 Link 组件外,路由库中还提供了 NavLink
组件,可以在路由匹配时获得一个高亮类名,从而指定高亮效果(样式需要自己手动指定)
使用方式同 Link 组件,只是额外获得一个高亮类名
activeClassName
属性:用于指定高亮的类名,默认 active
exact
属性:精确匹配,表示必须精确匹配(to 属性值和浏览器地址栏中的 pathname 相同),类名才生效
<NavLink to="/first">页面一</NavLink>
// 渲染为:
<a href="/first" class="active">页面一</a>
// ---
// Link 的模糊匹配和精确匹配
// 模糊匹配:
// 浏览器地址栏中的 pathname 为:/search/a
// 匹配成功的 to 属性为:
// 1 /search ==> 模糊匹配成功
// 2 /search/a ==> 完全相同,匹配成功
// 3 /sear ==> 匹配失败,因为 /search 是一块完整的内容,必须要出现这一整块内容才可以
// 精确匹配:
// 浏览器地址栏中的 pathname 为:/search/a
// 注意:添加 exact 属性后,变为精确匹配,此时,这个 NavLink 只能匹配 /search 这一个 patchname 了
// React 中如果属性是 布尔值 可以只写属性名称,不用写后面的 = 等内容
<NavLink exact to="/search">search 页面</NavLink>
// 等价于:
<NavLink exact={true} to="/search">search 页面</NavLink>
Route
组件:用来配置路由规则
path
属性,指定路由规则component
属性,指定要渲染的组件children
子节点,指定要渲染的组件// 用法一:使用 component 属性指定要渲染的组件
<Route path="/search" component={Search} />
// 用法二:使用 children 指定要渲染的组件
<Route path="/search">
<Search />
</Route>
注意:对于 Route 来说,如果路由规则匹配成功,那么,就会渲染对应组件;否则,渲染 null 或者说不渲染任何内容
对于 Route 组件来说,path
属性是可选的:
<Route>
<SomeComponent />
</Route>
路由有两种匹配模式:1 模糊匹配(默认), 2 精确匹配
模糊匹配
<Link to="/login">登录页面</Link>
<Route path="/" component={Home} /> 匹配成功
// pathname 代表Link组件的to属性(也就是 location.pathname)
// path 代表Route组件的path属性
path | 能够匹配的pathname(浏览器地址栏) |
---|---|
/ | 所有 pathname |
/first | /first 或 /first/a 或 /first/a/b/… |
精确匹配
exact
属性,让其变为精确匹配模式// 此时,该组件只能匹配 pathname=“/” 这一种情况
<Route exact path="/" component=... />
切换页面时,执行过程如下:
注意:默认情况下,React 路由可以同时匹配成功多个,只要匹配成功,该路由组件对应的内容就会渲染到页面中
Switch
组件:包裹 Route 组件,只会渲染第一个匹配的组件,即使有多个路由都可以匹配成功
Switch
组件包裹 Route
组件Switch
组件非常容易的就能实现 404 页面功能:<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/user">
<User />
</Route>
// 即使这个也可以匹配成功 /user/a 但是因为 Switch 组件的存在,这个路由对应的组件内容是不会渲染的
<Route path="/user/a">
<User1 />
</Route>
{/* 以上路由规则全都不匹配时,展示 404 页面 */}
{/* 注意:这个路由需要放在最后,兜底 */}
<Route>
<NoMatch />
</Route>
</Switch>
场景:点击登录按钮,登录成功后,通过代码跳转到后台首页,如何实现?
编程式导航:通过 JS 代码来实现页面跳转
可以通过useHistory
hook 来拿到路由提供的 history 对象,用于获取浏览器历史记录的相关信息。常用操作:
push(path)
:跳转到某个页面,参数 path 表示要跳转的路径replace(patch)
:跳转到某个页面,会替换当前的历史记录go(n)
: 前进或后退到某个页面,参数 n 表示前进或后退页面数量(比如:-1 表示后退到上一页)import { useHistory } from 'react-router-dom'
const Login = () => {
const history = useHistory()
const onLogin = () => {
// ...
history.push('/home')
}
return (
<button onClick={onLogin}>登录</button>
)
}
push(path)
和 replace(path)
跳转路由的区别:
浏览器会自动记录访问过来的页面路径,可以简单的把理解为通过一个 数组 来记录的。
比如:我们访问了 3 个页面:[‘/login’, ‘/home’, ‘/search’],当前所在页面为:’/search’
push('/a')
方法访问了一个新页面:’/a’,此时,就相当于往数组中 push 了一条数据,replace('/a')
方法访问了一个新页面:’/a’,此时,就相当于把当前页面地址,替换为 ‘/a’!评论内容需包含中文