【React-Router】路由传参,路由嵌套,手动导航,路由文件配置
文章目录
- React-Router
- URL的hash
- HTML5的History
- Router的基本使用
- 路由映射配置
- 路由的嵌套
- 路由配置和跳转
- Link和NavLink:
- 手动路由的跳转
- 路由参数传递
- Navigate导航
- Not Found页面配置
- 路由的配置文件
React-Router
前端路由是如何做到URL和内容进行映射呢?怎么原生的监听URL的改变。
URL的hash
URL的hash也就是锚点(#), 本质上是改变window.location的href属性;
我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;
hash的优势就是兼容性更好,在老版IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径。
hashchange事件触发时,事件对象会有hash改变前的URL(oldURL)和hash改变后的URL(newURL)两个属性:
window.addEventListener('hashchange',function(e) { console.log(e.oldURL); console.log(e.newURL) },false);
HTML5的History
◼ history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面:
replaceState:替换原来的路径;
pushState:使用新的路径;
popState:路径的回退;
go:向前或向后改变路径;
forward:向前改变路径;
back:向后改变路径;
popstate 事件是通过 window.addEventListener('popstate') 进行注册的。但触发条件需要满足下面两点:
点击浏览器的【前进】【后退】按钮,或者调用 history 对象的 back、forward、go 方法
之前调用过 history 对象的 replaceState 或 pushState 方法
Router的基本使用
◼ 安装React Router:
npm install react-router-do
◼ react-router最主要的API是给我们提供的一些组件:
◼ BrowserRouter或HashRouter
Router中包含了对路径改变的监听,并且会将相应的路径传递给子组件;
BrowserRouter使用history模式;
HashRouter使用hash模式;
-src
—index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import store from './store';
import { HashRouter,BrowserRouter } from 'react-router-dom';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(// <React.StrictMode><HashRouter><Provider store={store}><App /></Provider></HashRouter>// </React.StrictMode>
);
路由映射配置
◼ Routes:包裹所有的Route,在其中匹配一个路由
Router5.x使用的是Switch组件
◼ Route:Route用于路径的匹配;
path属性:用于设置匹配到的路径;
element属性:设置匹配到路径后,渲染的组件;
✓ Router5.x使用的是component属性
exact:精准匹配,只有精准匹配到完全一致的路径,才会渲染对应的组件;
✓ Router6.x不再支持该属性
-src
—App.jsx
import {Routes,Route
} from "react-router-dom";export class App extends PureComponent {render() {<Routes><Route path="/home" element={<Home />}></Routes>}}
路由的嵌套
◼ 在开发中,路由之间是存在嵌套关系的。
◼ 组件用于在父路由元素中作为子路由的占位元素。
-src
—pages
-------App.jsx
<Routes><Route path="/home" element={<Home />}><Route path="/home/homeChild" element={<HomeChild />}></Route></Route></Routes>
-src
—pages
-------Home.jsx
子路由的出口
组件用于在父路由元素中作为子路由的占位元素。
这样HomeChild组件就会被渲染到Home组件的占位元素的位置
export class Home extends PureComponent {render() {<div><h2>Home Page</h2><div>{/* 占位组件 */}<Outlet /></div></div>}}
路由配置和跳转
Link和NavLink:
通常路径的跳转是使用Link组件,最终会被渲染成a元素;
NavLink是在Link基础之上增加了一些样式属性,默认叫active的className,通过配置css可以让选中的标签展现active类名下的样式;
to属性:Link中最重要的属性,用于设置跳转到的路径;
-src
—App.jsx
import {Routes,Route
} from "react-router-dom";
import './style.css'export class App extends PureComponent {render() {<div><nav><Link to="/home">首页</Link><NavLink to="/home">首页</NavLink></nav><Routes><Route path="/home" element={<Home />}></Routes></div>}}
-src
—style.css
nav .active {color: red;font-size: 18px;
}
手动路由的跳转
◼ 实际上我们也可以通过JavaScript代码进行跳转。
我们知道Navigate组件是可以进行路由的跳转的,但是依然是组件的方式。
如果我们希望通过JavaScript代码逻辑进行跳转(比如点击了一个button),那么就需要获取到navigate对象。
◼ 在Router6.x版本之后,代码类的API都迁移到了hooks的写法:
如果我们希望进行代码跳转,需要通过useNavigate的Hook获取到navigate对象进行操作;
例子:
import {useNavigate,
} from "react-router-dom";export function RouterHook() {const navigate = useNavigate()return(<div><button onClick={e => navigate('/home')}>去home</button></div>)
}
那么如果是一个函数式组件,我们可以直接调用,但是如果是一个类组件呢?
类组件我们可以使用一个高阶组件包裹,在返回的组件的props中写入react-router-dom的方法,这里封装了useLocation, useNavigate, useParams, useSearchParams四个钩子
useParams和useSearchParams钩子:用来接收路由传参
useLocation钩子:监听路由的地址
useNavigate钩子:实现手动路由跳转
案例:
-src
—hoc
-------withRouter.js
import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom";function withRouter(WrapperComponent) {return function (props) {// 1.导航const navigate = useNavigate()// 2.动态路由的参数: /detail/:idconst params = useParams()// 3.查询字符串的参数: /user?name=why&age=18const [searchParams] = useSearchParams()const query = Object.fromEntries(searchParams)// 4.路由地址const location = useLocation()const router = { navigate, params, location, query }return (<WrapperComponent{...props}router={router}></WrapperComponent>);};
}export default withRouter
再到类组件中使用withRouter高阶组件包裹需要使用router hook的组件上
import withRouter from "../hoc/withRouter";export class Home extends PureComponent {....
}export default withRouter(Home);
路由参数传递
◼ 传递参数有二种方式:
动态路由的方式;
search传递参数;
◼ 动态路由的概念指的是路由中的路径并不会固定:
比如/detail的path对应一个组件Detail;
如果我们将path在Route匹配时写成/detail/:id,那么 /detail/abc、/detail/123都可以匹配到该Route,并且进行显示;
这个匹配规则,我们就称之为动态路由;
通常情况下,使用动态路由可以为路由传递参数。
路由传递参数
import {Link,Routes,Route,
} from "react-router-dom";export function App(props) { return (<div><Link to="/home/detail/123">给detail页面传参123</Link><Routes><Route path="/home/detail/:id" element={<Detail />}></Route></Routes></div>)
}
在组件中接收参数
import React, { PureComponent } from 'react'
import { withRouter } from '../hoc'export class Detail extends PureComponent {render() {const { router } = this.propsconst { params } = routerreturn (<div><h1>Detail Page</h1><h2>id: {params.id}</h2></div>)}
}export default withRouter(Detail)
◼ search传递参数
给Contexta组件路由传参
import {Link,Routes,Route,
} from "react-router-dom";export function App(props) { return (<div><Link to="/home/context?age=18&name=顽皮宝">给contexta页面传参</Link><Routes><Route path="/home/context" element={<Contexta />}></Route></Routes></div>)
}
在组件中接收参数
import React, { PureComponent } from 'react'
import { withRouter } from '../hoc'export class Contexta extends PureComponent {render() {const { router } = this.propsconst { query } = routerreturn (<div><h1>User: {query.name}-{query.age}</h1></div>)}
}export default withRouter(Contexta)
Navigate导航
◼ Navigate用于路由的重定向,当这个组件出现时,就会执行跳转到对应的to路径中:
j例子:在匹配到’/'的时候,直接跳转到/home页面
<Route path="/" element={<Navigate to="/home" />}></Route>
Not Found页面配置
◼ 如果用户随意输入一个地址,该地址无法匹配,那么在路由匹配的位置将什么内容都不显示。
◼ 很多时候,我们希望在这种情况下,让用户看到一个Not Found的页面。
开发一个Not Found页面;
配置对应的Route,并且设置path为*即可;
<Route path="*" element={<NotFound />}></Route>
路由的配置文件
◼ 目前我们所有的路由定义都是直接使用Route组件,并且添加属性来完成的。
◼ 但是这样的方式会让路由变得非常混乱,我们希望将所有的路由配置放到一个地方进行集中管理:
在早期的时候,Router并且没有提供相关的API,我们需要借助于react-router-config完成;
在Router6.x中,为我们提供了useRoutes API可以完成相关的配置;
◼ 如果我们对某些组件进行了异步加载(懒加载),那么需要使用Suspense进行包裹
-src
—router
-------index.js
import Home from '../pages/Home'
import HomeRecommend from "../pages/HomeRecommend"// import About from "../pages/About"
// import Login from "../pages/Login"
import { Navigate } from 'react-router-dom'
import React from 'react'// 懒加载
const About = React.lazy(() => import("../pages/About"))
const Login = React.lazy(() => import("../pages/Login"))const routes = [{path: "/",element: <Navigate to="/home"/>},{path: "/home",element: <Home/>,children: [{path: "/home/recommend",element: <HomeRecommend/>},]},{path: "/about",element: <About/>},{path: "/login",element: <Login/>},
]export default routes
-src
—App.jsx
import React from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'export function App(props) {return (<div className='app'><div className='nav'><Link to="/home">首页</Link><Link to="/login">登录</Link></div><div className='content'>{useRoutes(routes)}</div></div>)
}export default App
相关文章:
【React-Router】路由传参,路由嵌套,手动导航,路由文件配置
文章目录React-RouterURL的hashHTML5的HistoryRouter的基本使用路由映射配置路由的嵌套路由配置和跳转Link和NavLink:手动路由的跳转路由参数传递Navigate导航Not Found页面配置路由的配置文件React-Router 前端路由是如何做到URL和内容进行映射呢?怎么…...
面向对象分析与设计(OOAD)
面向对象分析与设计(OOAD)概述人是怎么认识事物的分类与分层的两种思维问题域到解空间的映射软件生命周期要解决的问题三个一致性面向对象分析与设计过程对象从哪里来发现对象的方法组织对象结构职责是怎么来的分配职责的逻辑验证职责分配的合理性GRASP设…...
数据库调优
目录 硬件层面 操作系统层面 数据库层面 硬件层面 1.CPU(运算):48核CPU。 2.内存:96G-256G,跑3-4个实例。 3.disk(磁盘IO):机械盘:选SAS,数量越多越好。性能:SSD(高并发)>SAS(普通业务线上)>SATA(线下) 选SSD:使用SSD或者PCIe SSD设备,可提升上千倍的IOPS…...
OpenStack云平台搭建(3) | 部署Glance
目录 1、登录数据库授权 2、安装glance 3、测试一下 安装部署Glance镜像服务 Image Service 镜像服务:代号:Glance:为云平台虚拟机提供镜像服务,例如:上传镜像、删除镜像等。说明:镜像:磁盘…...
软件评测师考试总结
软件评测师是软考中级考试项,每年一次考试机会,2022年的是在11月份举行,具体事项需查看软考官网。 分享一下个人的备考经验,以及总结一下这个学习的过程,有需要的可以酌情参考。 一、方法策略 获取信息 官网&#x…...
小白系列Vite-Vue3-TypeScript:009-屏幕适配
上一篇我们介绍了ViteVue3TypeScript项目中mockjs的安装和配置。本篇我们来介绍屏幕适配方案,简单说来就是要最大程度上保证我们的界面在各种各样的终端设备上显示正常。通用的屏幕适配方案有两种:① 基于rem 适配(推荐,也是本篇要…...
查找企业微信聊天记录,会话存档有多重要
会话存档是基于企业微信API插口而开发设计的聊天记录查询专用工具。运用会话存档能不能找到误删除、到期的聊天记录呢?实际上能否通过会话存档找到企业微信中的聊天记录分两种状况,大家一起来看看吧:开启会话存档前的聊天记录没法找到和开启会…...
C语言经典编程题100例(1-20)
1、练习2-1 Programming in C is fun!本题要求编写程序,输出一个短句“Programming in C is fun!”。输入格式:本题目没有输入。输出格式:在一行中输出短句“Programming in C is fun!”。代码:#include<stdio.h> int main() {printf("Progra…...
小白系列Vite-Vue3-TypeScript:008-安装配置mock
上一篇我们介绍了ViteVue3TypeScript项目中axios的安装和配置,并手动封装了api。本篇我们来在上篇基础上介绍如何引入mock,并在本地模拟后台接口请求来达到本地测试的目的。在现在前后端分离的开发模式中,前端页面很多渲染的数据都需要通过ht…...
OnGUI Box 控件||Unity 3D OnGUI 常用控件
OnGUI Box 控件Unity 3D Box 控件用于在屏幕上绘制一个图形化的盒子。Box 控件中既可以显示文本内容,也可以绘制图片,或两者同时存在。GUIContent 和 GUIStyle 对于 Box 控件同样适用,既可以用来修饰 Box 控件的文本颜色,也可以用…...
shiro721——CVE-2019-12422
这两个漏洞主要区别在于Shiro550使⽤已知密钥碰撞,后者Shiro721是使⽤ 登录后rememberMe {value}去爆破正确的key值 进⽽反序列化,对⽐Shiro550条件只要有 ⾜够密钥库 (条件⽐较低)、Shiro721需要登录(要求⽐较⾼鸡肋 …...
爬虫JS逆向思路 - - 扣JS(data解密)
网络上几千块都学不到的JS逆向思路这里全都有👏🏻👏🏻👏🏻 本系列持续更新中,三连关注不迷路👌🏻 干货满满不看后悔👍👍👍 ❌注意…...
Android 进阶——Framework 核心之Binder 相关预备理论(一)
文章大纲引言一、进程的内存空间和进程隔离二、Linux 系统内存的用户空间和内核空间1、用户空间(User Space)2、内核空间(Kernel Space)三、Linux IPC 原理1、内核态和用户态2、IPC 步骤四、内核模块和驱动五、Binder1、Binder IP…...
【23种设计模式】结构型模式详细介绍
前言 本文为 【23种设计模式】结构型模式 相关内容介绍,下边将对适配器模式,桥接模式,组合模式,装饰模式,外观模式,亨元模式,代理模式,具体包括它们的特点与实现等进行详尽介绍~ &a…...
接口自动化实战-postman
1.测试模型 单元测试并非测试工程师的本职工作,它属于开发工程师的工作,开发进行单元测试的情况我们不知道,为了确保系统尽可能没有Bug,于是接口测试在测试工程师这里就变得由为重要了。实际工作中为菱形模型。 接口测试能更早的…...
前端跨域方案简单总结
1、什么是跨域 【】跨域是一种浏览器同源安全策略,也即浏览器单方面限制脚本的跨域访问。很多人可能误认为资源跨域时无法请求,实质上请求是可以正常发起的(指通常情况下,部分浏览器存在部分特例),后端也可…...
【HTML】HTML 表格 ② ( 表头单元格标签 | 表格标题标签 )
文章目录一、表头单元格标签二、表格标题标签一、表头单元格标签 表头单元格 可以在表格中 用作第一排 作为表格 的 表头 使用 , 表头单元格 中的 文本设置 可以与 普通单元格 中的文本设置 不同 ; 表头单元格 中的 文本 会 居中 , 并且 加粗 显示 ; 表头单元格 标签 如下 : &…...
常用的辅助类2(StringBuilder、StringBuffer、处理时间相关的类、对象比较器)
Java知识点总结:想看的可以从这里进入 目录7.7、字符串相关类7.8、时间处理7.8.1、JDK8前7.8.2、JDK8后1、时间日期类2、格式化日期3、其他7.9、对象比较器7.7、字符串相关类 String:JDK1.0出现,字符串类,被final修饰其值不可改。…...
anaconda下pytorchCPU GUP安装及问题记录
1 pytorch安装(CPU版本) pip3 install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple2 torchvision、torchaudio、torchtext安装:解决ModuleNotFoundError: No module named ‘torchvision‘问题 (…...
香港中文大学MISC Lab GNN团队: 异质图神经网络研究进展从谱的角度看待(图)对比学习(图自监督学习)
简介 实验室简介 香港中文大学机器智能与社会计算实验室(MISC Lab, Machine Intelligence and Social Computing Lab) 由Prof. Irwin King 创建并不断发展, 在图学习,推荐系统,自然语言处理,机器学习等领域取得了卓越的研究成果。在图学习方面, MISC Lab关注异质图学习(Het…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
