React 路由

路由的基本理解

SPA 理解

  • 单页 Web 应用 (single page web application, SPA)
  • 整个应用只有一个完整的页面
  • 点击页面中的链接不会刷新页面,只会做页面的局部更新
  • 数据都需要通过 ajax 请求获取,并在前端异步展现

前端路由的理解

  • 游览器端路由: value 是 component,用于展示页面内容
  • 注册路由:<Route path="/test" component={Test}>
  • 工作过程:当游览器的 path 变为 /test 时,当前路由组件就会变为 Test 组件

react-router-dom 的理解

  • react 的一个插件库
  • 专门用来实现一个 SPA 应用
  • 下载代码 npm add react-router-dom

路由的基本使用

import React, { Component } from 'react';
import { Link, BrowserRouter, Route } from 'react-router-dom';
import About from './pages/About'; // 导入 About 路由组件
import Home from './pages/Home'; // 导入 Home 路由组件

export default class App extends Component {
  render () {
    return (
      <div>
        {/* 在 react 中靠路由链接切换组件 --- 编写路由链接 */}
        <BrowserRouter>
          <Link to="/about">about</Link>
          <br />
          <Link to="/home">home</Link>

          {/*  注册路由 */}
          <Route path="/about" component={About}></Route>
          <Route path="/home" component={Home}></Route>
        </BrowserRouter>
      </div>
    )
  }
}

NavLink 与 Link 的区别

  • NavLink 可以让元素被点击时加上 activeClassName 的样式
<NavLink activeClassName="active" to="/about">about</NavLink>

Switch 的使用

  • 通常情况下,path 和 component 是一一对应关系
  • Switch 可以提高路由匹配效率(单一匹配)
<Switch>
  <Route path="/about" component={About}></Route>
  <Route path="/home" component={Home}></Route>
  {/*  home路由 只展示上面这个组件,不向下匹配了 */}
  <Route path="/home" component={Home}></Route>
</Switch>

路由重定向

  • 一般写在所有路由的最下方
  • 一般用来跳转首页
// 引入
import { Redirect, NavLink, BrowserRouter, Route } from 'react-router-dom';
// 使用
<Route path="/about" component={About}></Route>
<Route path="/home" component={Home}></Route>
<Redirect to="/about" />

路由嵌套

  • 路由嵌套不能使用精准匹配,必须使用模糊匹配

  • 注册子路由时要写上父路由的 path 值

  • 路由的匹配是按照注册路由的顺序进行的

  • 我们在 Home 文件夹下添加两个子文件

    • Home_children1
    • Home_children2
  • Home 代码

import React, { Component } from 'react';
import { NavLink, BrowserRouter, Route } from 'react-router-dom';
import children1 from './children/Home_children1';
import children2 from './children/H ome_children2';

export default class About extends Component {
  render () {
    return (
      <div>
        显示Home的内容
        <br />
        {/* 在 react 中靠路由链接切换组件 --- 编写路由链接 */}
        <BrowserRouter>
          <NavLink activeClassName="active" to="/home/children1">about</NavLink>
          <br />
          <NavLink activeClassName="active" to="/home/children2">home</NavLink>

          {/*  注册路由 */}
          <Route path="/home/children1" component={children1}></Route>
          <Route path="/home/children2" component={children2}></Route>
        </BrowserRouter>
      </div>
    )
  }
}

路由组件传递参数

路由组件传递 params 参数

  • 跳转并传递参数
    • 路由链接:<Link to="/demo/test/tom/18">详情</Link>
    • 编程式路由: this.props.history.push('/demo/test/tom/18')
  • 注册路由(接受参数):<Route path="/demo/test/:name/:age" component={Test}/>
  • 接收参数:this.props.match.params

路由组件传递 search 参数

  • 跳转并传递参数
    • 路由链接:<Link to="/demo/test/?name=tom&age=1">详情</Link>
    • 编程式路由: this.props.history.push('/demo/test/?name=tom&age=1')
  • 注册路由(无需声明,直接注册即可):<Route path="/demo/test" component={Test}/>
  • 接收参数:this.props.location.search
    • 获取到的 search 是 urlencoded 编码字符串,需要借助 querystring 解析

路由组件传递 state 参数

  • 跳转并传递参数
    • 路由链接:<Link to={{path:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
    • 编程式路由: this.props.history.push('/demo/test',{name:'tom',age:18})
  • 注册路由(无需声明,直接注册即可):<Route path="/demo/test" component={Test}/>
  • 接收参数:this.props.location.state
    • 刷新也不会丢失参数

将 push 模式改为 replace 模式

<Link replace to="/demo/test/tom/18">详情</Link>
this.props.history.replace('/demo/test/tom/18')

编程式路由的其它三个方法

goback 回退一步

this.props.history.goback()

goforwrd 前进一步

this.props.history.goforwrd()

go 前进或回退

  • 参数
    • 类型为 number
    • 正数为前进,负数为后退
    • 数字为前进或回退几次
      this.props.history.go(-1)

一般组件使用编程式路由的方法

  • 一般组件无法直接使用编程式路由的方法,必须使用 withRouter 加工,让一般组件具备路由组件所特有的 API
  • withRouter 返回的是一个新组件
import React, { Component } from 'react';
import {withRouter} from 'react-router-dom';

class Header extends Component {
}
export default withRouter(Header)

BrowserRouter 与 HashRouter 的区别

  • 底层原理不一样
    • BrowserRouter 使用的是 H5 的 history API,不兼容 IE9 以下的版本
    • HashRouter 使用的是 URL 的哈希值
  • path 的表现形式不一样
    • BrowserRouter 的路径中没有#,例如:localhost:3000/demo/test
    • HashRouter 的路径中没有#,例如:localhost:3000/#/demo/test
  • 刷新后对路由 state 参数的影响
    • BrowserRouter 没有任何影响,因为 state 保存在 history 对象中
    • HashRouter 刷新后会导致路由 state 参数的丢失
  • 备注:HashRouter 可以用于解决一些路径错误相关的问题
posted @ 2021-08-07 16:01  懒惰ing  阅读(204)  评论(0编辑  收藏  举报