1. React路由介绍
现代的前端应用大多都是SPA
(单页应用程序), 也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器的压力更小,所以更受欢迎。为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生。
- 前端路由的功能:让用户从一个视图(页面)导航到另一个视图(页面)
- 前端路由是一套映射规则 ,在React中,是
URL路径
与组件
的对应关系 - 使用React路由简单来说,就是配置
路径
和组件
(配对)
2. 路由的基本使用
使用步骤:
- 安装:在VScode开启终端,使用命令
yarn add react-router-dom
或npm install react-router-dom
安装 - 导入路由的三个核心组件:
Router
/Route
/Link
- 使用
Router组件
包裹整个应用(重要) - 使用Link组件作为导航菜单(路由入口)
- 使用Route组件配置路由器规则和要展示的组件(路由出口)
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
// 2. 导入路由的三个核心组件:`Router` / `Route` / `Link`
import {
BrowserRouter as Router , Route, Link } from 'react-router-dom'
const First =()=><p>页面一的内容</p>
const App = () => {
// 3. 使用`Router组件`包裹整个应用(重要)
<Router>
<div>
<h1>React路由基础</h1>
{
/* 4. 使用Link组件作为导航菜单(路由入口) */}
<Link to="/first">页面一</Link>
{
/* 5. 使用Route组件配置路由器规则和要展示的组件(路由出口) */}
<Route path="/first" component={
First} />
</div>
</Router>
}
ReactDOM.render(<App />,document.getElementById('root'))
常用组件说明
- React组件:包裹整个应用,一个React应用只需要
使用一次
- 两种常用Router:HashRouter和
BrowserRouter
- HashRouter:使用URL的哈希值实现(localhost:3000/#/first)
- (推荐)
BrowserRouter
:使用H5的history API实现(localhost:3000/first) - Link组件:用于指定导航链接(a标签)
//to属性:浏览器地址栏中的pathname(location.pathname)
<Link to="/first">页面一</Link>
- Router组件:指定路由展示组件相关信息
//path:属性:路由规则
//component属性:展示的组件
//Route组件写在哪,渲染出来的组件就展示在哪
<Route path="/first" component={
First} />
代码实现:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
// 2. 导入路由的三个核心组件:`Router` / `Route` / `Link`
import {
BrowserRouter as Router , Route, Link } from 'react-router-dom'
const First =()=><p>页面一的内容</p>
const Home = () => <h2>这是Home组件的内容</h2>
const App = () => {
// 3. 使用`Router组件`包裹整个应用(重要)
<Router>
<div>
<h1>React路由基础</h1>
{
/* 5. 使用Route组件配置路由器规则和要展示的组件(路由出口) */}
<Route path="/first" component={
First} />
<Route path="/home" component={
Home} />
{
/* 4. 使用Link组件作为导航菜单(路由入口) */}
<Link to="/first">页面一</Link>
<Link to="/home">页面一</Link>
</div>
</Router>
}
ReactDOM.render(<App />,document.getElementById('root'))
3. 路由的执行过程
- 点击 Link 组件(a标签),修改了浏览器地址栏中的 url 。
- React 路由监听到地址栏 url 的变化。
- React 路由内部遍历所有 Route 组件,使用路由规则( path )与 pathname 进行匹配。
- 当路由规则(path)能够匹配地址栏中的 pathname 时,就展示该 Route 组件的内容。
4. 编程式导航
- 场景:点击登录按钮,登录成功后,通过代码跳转到后台首页,如何实现?
- 编程式导航:
通过JS代码来实现页面跳转
- history是React路由提供的,用于获取
浏览器历史记录
的相关信息 push(path)
:跳转到某个页面,参数path表示要跳转的路径go(n)
:前进或后退到某个页面,参数n表示前进或后退页面数量(比如:表示后退到上一页)
class Login extends React.Component{
handleLogin = () => {
// 使用编程式导航实现路由跳转
//省略其他功能代码
this.props.history.push('/home')
}
render() {
...}
}
代码实现:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import {
BrowserRouter as Router , Route, Link } from 'react-router-dom'
class Login extends React.Component{
handleLogin = () => {
// 使用编程式导航实现路由跳转
//省略其他功能代码
this.props.history.push('/home')
}
render() {
return (
<div>
<p>登录页面</p>
<button onClick={
this.handleLogin}>登录</button>
</div>
)
}
}
const Home =props => (
const handleBanck =()=>{
// go(-1) 表示返回上一个页面
props.history.go(-1)
}
<div>
<h2>我是后台首页</h2>
<button onClick={
handleBack}></button>
</div>
)
const App = () => (
<Router>
<div>
<h1>编程式导航:</h1>
<Link to='"/login'>去登录页面</Link>
<Route path="/login" component={
Login}></Route>
<Route path="/home" component={
Home}></Route>
</div>
</Router>
)
ReactDOM.render(<App />,document.getElementById('root'))
5. 默认路由
问题:现在的路由都是点击导航菜单后展示的,如何在进入页面的时候就展示呢?
答:
- 使用默认路由:
表示进入页面时就会匹配的路由
- 默认路由path为:
/
<Route path="/" component={
Home}></Route>
代码实现:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import {
BrowserRouter as Router , Route, Link } from 'react-router-dom'
const Home =props => (
<div>
<h2>我是后台首页</h2>
<button onClick={
handleBack}></button>
</div>
)
const App = () => (
<Router>
<div>
<h1>默认路由</h1>
{
/* 默认路由 */}
<Route path="/" component={
Home}></Route>
</div>
</Router>
)
ReactDOM.render(<App />,document.getElementById('root'))
6. 匹配模式
模糊匹配模式
- 问题:当Link组件的to属性值为"/login" 时,为什么默认路由也被匹配成功
- 默认情况下, React路由是
模糊匹配模式
- 模糊匹配规则:只要pathname
以path开头
就会匹配成功
<Link to="/login">登录页面</Link>
<Route path="/" component={
Home}></Route>//匹配成功
//path 代表Route组件的path属性
//pathname 代表Link组件的t为属性(也就是 location.pathname
例:
path | 能够匹配的所有pathname |
---|---|
/ | 所有pathname |
/first | /first 或 /first/a 或/first/a/b… |
精确匹配
- 问题:默认路由任何情况下都会展示,如何避免这种问题?
- 给Route组件添加
exact
属性,让其变为精确匹配模式
- 精确匹配:只有当
path
和pathname
完全匹配时才会展示该路由
//此时,该组件只能匹配pathname="/"这一种情况
<Route exact path="/" component=.../></Route>
推荐:给默认路由添加exact属性
代码实现:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import {
BrowserRouter as Router , Route, Link } from 'react-router-dom'
const Login =()=> <p>我是Login组件的内容</p>
const Home =props => (
<div>
<h2>我是后台首页</h2>
<button onClick={
handleBack}></button>
</div>
)
const App = () => (
<Router>
<div>
<h1>默认路由</h1>
<ul>
<li>
<Link to="/">首页</Link>
</li>
<li>
<Link to="/login">登录页面</Link>
</li>
</ul>
{
/* 默认路由,添加exact属性,就会让当前路由变为精确匹配 */}
<Route exact path="/" component={
Home}></Route>
<Route path="/login" component={
Login}></Route>
</div>
</Router>
)
ReactDOM.render(<App />,document.getElementById('root'))