当前位置: 首页 > news >正文

react笔记_10react路由

目录

      • 什么叫做路由?
      • 路由组件与一般组件区别
      • react中配置路由
          • [1] 下载
          • [2] 注册路由
            • Switch
          • [3] 导航区(路由跳转)
            • 编程式导航
          • [4] 路由出口
          • [5] 路由重定向
          • [6] 路径的模糊匹配与严格匹配
          • [7] 嵌套路由
          • [8] 路由传参
            • 1.search参数
            • 2.state参数
            • 3.params参数
            • 编程式导航路由传参
        • 路由配置封装

什么叫做路由?

一个路由就是一个映射关系(key:value)
key为路径, value可能是function或component

  • function: 后端路由,用来处理客户端提交的请求;
  • component:前端路由,用于展示页面内容;

路由组件与一般组件区别

  • 写法不同:
    • 一般组件:<Demo/>
    • 路由组件: <Route path="/demo" component={Demo}/>
  • 存放位置不同:
    * 一般组件: components
    * 路由组件: pages
  • 接收到的props不同:
    • 一般组件: 写组件标签时传递了什么,就能收到什么
    • 路由组件: 接收带三个固定的属性

react中配置路由

在react中使用 react-router-dom(插件) 来进行路由的配置

[1] 下载

使用npm i react-router-dom 命令下载 路由插件;

  • 报错:A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .
  • 原因:我下载时使用的命令是npm i react-router-dom 下载的是最新版本(6版本)—语法不兼容了
  • 解决:npm i react-router-dom@5.2.0 下载6以下的版本
[2] 注册路由

在下载了 react-router-dom 插件之后,就可以通过 react-router-dom包引入 Route组件注册路由。

Route组件包含以下属性

  • path: 路由的路径
  • component: 组件
  • exact: 是否进行严格匹配(默认模糊匹配)

以下就注册了一个 Home 组件 ,组件路径为/home。

// [1]引入注册路由组件
import {Route} from 'react-router-dom'
// [2] 引入组件
import Home from '../src/pages/Home'
// [3] 注册组件
<Route path='/home' component={Home}></Route>
Switch

在注册路由时如下:可能有两个甚至多个的路由注册,通过 下面代码 注册路由 当path变为/home时 路由出口的位置展示哪个组件-- Home组件orTest组件or两个都展示?

 <Route path='/about' component={About}/>
 <Route path='/home' component={Home}/>
 <Route path='/home' component={TEst}/>
  • 答案:两个都展示
  • 原因:路由的匹配规则为-> 从第一个开始匹配直至最后一个,即使找到对应路由也不会停止寻找
  • 问题:正常情况下,我们配置路由和路径时是 一一对应 的关系,因此这样的匹配规则是非常浪费性能的;
  • 解决:将 注册路由的代码 使用 switch 组件包裹 ;
  • 使用switch包裹后的匹配规则: 从第一个开始寻找,找到一个对应的路由则匹配结束;

通过 下面代码 注册路由 当path变为/home时仅仅展示Home组件

 <Switch>
   <Route path='/about' component={About}/>
   <Route path='/home' component={Home}/>
   <Route path='/home' component={Nested}/>
</Switch>
[3] 导航区(路由跳转)

在下载了 react-router-dom 插件之后,就可以通过 react-router-dom包引入 LinkNavLink 组件进行导航(路由跳转)。

Link组件包含以下属性

  • to: 点击之后需要跳转的路由路径
  • replace:是否覆盖当前路径

NavLink组件包含以下属性

  • to: 点击之后需要跳转的路由路径
  • activeClassName: 点击之后的样式的类名
  • replace:是否覆盖当前路径

以下就注册了一个 Home 组件 ,组件路径为/home;配置了一个跳转到home组件的链接,当点击“点我跳转到home组件”页面路径就变为/home了。

import {Component} from 'react'
import Home from '../src/pages/Home'
import {Link, Route} from 'react-router-dom'
export default class App extends Component {
  render(){
    return (
      <div>
        <Link to='/home'>点我跳转到home组件</Link>
        <Route path='/home' component={Home}></Route>
      </div>
    )
  }
}
编程式导航

除了上述通过组件进行路由跳转,也可以通过编程式导航进行路由跳转;

语法-借助prosp.history对象上的API对操作路由跳转、前进、后退

this.prosp.history.push()
this.prosp.history.replace()
this.prosp.history.goBack()
this.prosp.history.goForward()
this.prosp.history.go()
[4] 路由出口

路由分为两类:

  • Browser路由: 路径和正常路径相同(与vue中history路由原理相同)
  • Hash路由:路径中存在#(与vue中hash路由原理相同)

路由出口

  • 若是Browser路由则路由出口为 <BrowserRouter>;
  • 若是Hash路由则路由出口为 <HashRouter>;

下面配置表示该项目使用的是 Browser路由:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </BrowserRouter>
);

下面配置表示该项目使用的是 Hash路由:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { HashRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <HashRouter>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </HashRouter>
);
[5] 路由重定向
 <Switch>
   <Route path='/about' component={About}/>
   <Route path='/home' component={Home}/>
   <Route path='/nested' component={Nested}/>
</Switch>

以上是注册的几个路由,但是一进入页面时,匹配不到任何的路由,此时若是我们想进入页面(url为空)时默认展示home组件的内容,可以使用路由重定向。
Redirect组件包含以下属性

  • to: 路由重定向的路径

在下载了 react-router-dom 插件之后,就可以通过 react-router-dom包引入 Redirect组件进行路由重定向。

Redirect写在注册路由的下方(兜底)—当所有路由都匹配不上时 自动跳转到Redirect设置的路径上。

 <Switch>
   <Route path='/about' component={About}/>
   <Route path='/home' component={Home}/>
   <Route path='/nested' component={Nested}/>
   <Redirect to='/home' />  
</Switch>

在上方路径匹配后,当在浏览器输入路径 http://localhost:3000,默认路径会变为 http://localhost:3000/home

[6] 路径的模糊匹配与严格匹配

在路由跳转时,我们需要将 Link组件的to属性值 与 Route组件的path属性值进行匹配

  • 严格匹配:只有编写路由路径的link和注册路由的path 一模一样时才能成功显示对应的路由
  • 模糊匹配:会将to属性值以 / 划分 为 home a b, path属性同样以/进行划分为home,然后将path划分值按照顺序和to属性值进行匹配 只要path属性值匹配完毕且全部对应(to属性值存在剩余没有关系)则称为匹配

模糊匹配举例说明

<Link to='/home'></Link> 
<Route path='/home' component={Home}/>

可以成功跳转

 <Link to='/home/a/b'></Link> 
 <Route path='/home' component={Home}/>

可以成功跳转

<Link to='/a/home/a/b'></Link> 
<Route path='/home' component={Home}/> 

不能成功跳转

注意:不要随意开启严格匹配,否则会出现一些问题 比如嵌套路由无法匹配

[7] 嵌套路由

首先明确一点:路由的匹配是按照注册路由的顺序进行的.

举例说明
在App.vue(跟组件)注册了 Home路由和About路由,在Home组件注册了 Sun1和Sun2 两个子路由

  • App.jsx
    import About from '../src/pages/About'
    import Home from '../src/pages/Home'
    import {Link,NavLink, Route,Switch,Redirect} from 'react-router-dom'
    import {Component} from 'react'
      export default class App extends Component {
      render(){
        return (
          <div>
            <div className='left'>
              <Link to='/about'>About</Link> 
              <br />
              <NavLink activeClassName='active' to='/home'>Home</NavLink>
              <br />
              <Link to='/home/sun1'>sun1</Link>
              <br />
              <Link to='/home/sun2'>sun2</Link>
            </div>
            <div className='right'>
              <Switch>
                <Route path='/about' component={About}/>
                <Route path='/home' component={Home}/>
                <Redirect  to='/home' />
              </Switch>
            </div>
          </div>
        )
      }
    }
    
  • Home组件
    import React, { Component } from 'react'
    import {Route,Switch} from 'react-router-dom'
    import Sun1 from './New'
    import Sun2 from './New2'
    export default class Home extends Component {
      render() {
        return (
          <div>
            我是home组件
            <Switch>
              <Route path='/home/sun1' component={Sun1}></Route>
              <Route path='/home/sun2' component={Sun2}></Route>
            </Switch>
          </div>
        )
      }
    }
    
  • 当进入页面的路径为/home/sun2时
  • 渲染过程
    • 在渲染过程中先渲染App.vue, 发现页面有注册路由-> 进行路由匹配
    • 经过模糊匹配 Home组件被匹配(/home) -> 渲染home组件
    • 在渲染过程中,发现Home组件中也进行了路由注册->进行路由匹配
    • 经过模糊匹配 发现与Sun2组件完全对应(/home/sun2), 渲染Sun2组件
  • 通过匹配过程我们也可以看出 注册子路由时要写上父路由的path值 不然最初的匹配就失败!
[8] 路由传参

通过路由向组件传参一共有三种方式

1.search参数
  • 传参
    <Link to='url?参数名=参数值&参数名=参数值'></Link>
    
  • 接收
      this.props.location.search // String
    
  • 举例说明
    <Link to='/home/sun1?name=111&age=18'>sun1</Link>
    
    在子组件接收
    console.log('search参数', this.props.location.search) // search参数 ?name=111&age=18
    
    接收到的是 urlencoded编码字符串,需要借助querystring解析
  • querystring插件使用
    • [1] 下载
      使用npm install querystring -D命令下载
    • [2] 引入
      import qs from 'querystring'
      
    • [3] 解析参数
      console.log('search参数', qs.parse(this.props.location.search.split('?')[1]) ) // search参数 {name: '111', age: '18'}
      
2.state参数
  • 传参
    <Link to={{pathname:url, state:{参数名:参数值}}}></Link>
    
  • 接收
      this.props.location.state // Object
    
  • 举例说明
    <Link to={{pathname:'/home/sun1', state:{name:'111', age:18}}}>sun1</Link>
    
    在子组件接收
    console.log('state', this.props.location.state ) // state {name: '111', age: 18}
    
3.params参数
  • 传参
    <Link to=‘url/参数值/参数值’></Link>
    
  • 声明
      <Route path="/demo/test/:参数名/:参数值" component={Test}/>
    
  • 接收
      this.props.match.params // Object
    
  • 举例说明
    <Link to='/home/sun1/111/18'>sun1</Link>
    
    <Route path='/home/sun1/:name/:age' component={Sun1}></Route>
    
    在子组件接收
    console.log('state', this.props.match.params ) // params {name: '111', age: '18'}
    
编程式导航路由传参
// search参数
this.props.history.push('url?参数名=参数值')

// state参数
this.props.history.push(url,{参数名,参数值})

// params参数
this.props.history.push('/home/message/detail/参数值')

路由配置封装

111
以下代码的含义是当路径为/about时就跳转到About组件

<Route path='/about' component={About}/>
<Route path='/about' render={(props)=>{
  // 逻辑跳转
  // 如果符合条件->跳转到About组件
  if(xxx){
    return <About />
  }else{
    return <Redirect to='/login' />
  }
}}/>

相关文章:

  • 33页企业内容管理与应用建设整体解决方案
  • JavaFX爱好者看过来,这款工具值得拥有
  • 三角函数公式
  • 面向工业园区的5G垂直组网类服务探讨
  • URLLC关键技术研究与空口时延分析
  • YOLOv5s.yaml文件解读
  • 数据管理篇之数据质量
  • 5G无线技术基础自学系列 | 5G接入类KPI
  • 彻底卸载2345王牌输入法的方法
  • Python解题 - CSDN周赛第17期 - 拯救公主
  • ImportError: DLL load failed while importing etree: 找不到指定的模块。
  • 太神了!开源大佬的SpringBoot+微服务架构笔记,一般人真肝不出来
  • 为何推荐首选enum class 而非 enum
  • 红队隧道应用篇之Burpsuite设置上游代理访问内网(五)
  • 逆天了!用Numpy开发深度学习框架,透视神经网络训练过程
  • 渗透攻击MS08-067
  • 2022年全国职业院校技能大赛中职组网络安全竞赛试题B模块 —wirehark数据分析与取证captureWH.pcapng(解析教程)
  • vcpkg踩坑记录
  • Apache Spark 练习五:使用Spark进行YouTube视频网站指标分析
  • 【Javassist】快速入门系列05 当有指定方法调用时替换方法调用的内容