【React】路由器 React-Router

  • 安装
  • 路由模式
  • 路由组件和属性 (Link、NavLink、Outlet、Routes、Navigate、element)
  • 路由传参 ( Hook:useParams 、useSearchParams )
  • 路由跳转(Hook:useNavigate)
  • 路由的构建

前端路由指的是一种将浏览器URL与特定页面或视图关联起来的技术。在传统的Web开发中,当用户点击链接或者输入URL时,服务器会接收到请求并返回相应的HTML页面。而在前端路由中,当用户点击链接或者输入URL时,浏览器会根据路由规则对URL进行解析,并使用JavaScript控制页面的展示。

前端路由通常使用JavaScript库来实现,比如React Router、Vue Router等。它们允许开发者定义路由规则,并根据这些规则来显示不同的组件或页面

前端路由可以提高Web应用的性能和用户体验,因为它允许应用实现快速的页面切换和动态的内容加载,同时减少了服务器的负载

安装

官网:https://reactrouter.com/homeReactRouter包含三个内容:(1) react-router:核心库;(2) react-router-dom:正常PC用的;(3) react-router-native:移动native用的当前使用版本:"react-router-dom": "^6.30.0"安装:npm install react-router-dom@6

路由模式

React的路由需要在某个模式下包裹使用,不能单独使用

HashRouter(哈希路由):类似a标签锚点,在本页跳转,所以拿不到历史记录,因为没有跳出当前页面http://localhost:3000/#/homeHistory(在React中叫BrowserRouter,历史记录模式):模拟历史记录模式,可以有前进后退的历史记录http://localhost:3000/home//刷新页面,<BrowserRouter>会将当前路由发送到服务器//需要后端配合就是当收到请求的url不是功能性的,而是前端路由时,重新加载入口html文件

路由组件和属性 (Link、NavLink、Outlet、Routes、Navigate、element)

Link:负责跳转NavLink:将包裹的内容渲染为a标签,并给Link加上一个样式active类,设置类的样式达到激活菜单的效果Outlet:相当于一个占位符,目的就是为了用来占位展示当前组件对应的Home1和Home2(类似于vue中的router-view)Routes:路由拦截并展示对应的组件<Routes><Route path={"/home"} element={<Home/>}/><Route path={"/about"} element={<About/>}/></Routes>element:表示对应组件Navigate:相对于重定向路由嵌套的时候:子组件的path不需要写斜杠"/",直接写就好<Route path={"/home"} element={<Home/>}><Route path="home1" element={<Home1/>}/><Route path="home2" element={<Home2/>}/></Route>默认展示组件:<Route index element={<Home1/>}/>  <!--index表示默认要展示的组件,去掉path-->

src\App.js

import './App.scss';
import {HashRouter,  //-----路由容器,装路由组件// Link,  //-----跳转Routes,  //-----路由拦截展示的容器Route,  //-----拦截路径,设置展示组件Navigate,  //-----类似重定向NavLink,  //-----跳转,带active类,但需要自己写样式// BrowserRouter  //-----路由容器,装路由组件//Outlet  //-----占位符,用来展示嵌套路由的子组件的内容
} from 'react-router-dom';import Home from "./Home";
import About from "./About";
import Home1 from "./Hom1";
import Home2 from "./Home2";// 用户乱输入地址栏url,则返回404页面组件
const Err=()=><div>Error错误404页面</div>//React-Router案例
function App() {return (<>{/*<BrowserRouter>*/}<HashRouter future={{v7_startTransition: true,v7_relativeSplatPath: true/*解决:使用react-router-dom@6.30.0版本时,组件默认打印未来版本的警告信息,影响项目代码功能调试*/}}>{/*<Link to={"/home"}>Home</Link>*/}  {/*你要去哪里*/}<NavLink to={"/home"}>Home</NavLink>{/*<Link to={"/about"}>About</Link>*/}{/*<NavLink to={"/about/月亮/25"}>About</NavLink>*/}  {/*路由传参*/}<NavLink to={"/about?a=1&b=2"}>About</NavLink><Routes> {/*拦截并展示对应的组件*/}<Route path="/" element={<Navigate to={"/home"}/>}/>  {/*通用拦截*/}<Route path={"/home"} element={<Home/>}>{/*<Route path={"home1"} element={<Home1/>}/>  /!*嵌套子路由*!/*/}<Route index element={<Home1/>}/>  {/*index表示默认要展示的组件,去掉path*/}<Route path={"home1"} element={<Home1/>}/>  {/*加上这一行即可,因为上一行没法拦截对应路由,它本身还是要写*/}<Route path={"home2"} element={<Home2/>}/></Route>{/*<Route path={"/home/"} element={<Navigate to={"/home/home1"}/>}/>   /!*默认要展示的组件(自想方法)*!/*/}{/*<Route path={"/about/:name/:id"} element={<About/>}/>*/}   {/*路由接参*/}<Route path={"/about"} element={<About/>}/><Route path={"*"} element={<Err/>}/>  {/*错误404页面*/}</Routes></HashRouter>{/*</BrowserRouter>*/}</>);
}export default App;
import {NavLink, Outlet} from "react-router-dom";const Home = () => <div><h1>Home</h1><NavLink to={"/home/home1"}>Home1</NavLink><NavLink to={"/home/home2"}>Home2</NavLink><Outlet/> {/*占位符,用来展示Home1和Home2内容的*/}
</div>;export default Home;

路由传参 ( Hook:useParams 、useSearchParams )

import引入的路由都是引入的属性(大写开头);除了属性之外,路由还可以引入方法(所有的方法都是useXxx的格式)

路由传参(useParams):1. <NavLink to={"/about/25"}>About</NavLink>   <!--带参跳转,可以传递多个参数,右斜杠隔开-->2. <Route path={"/about/:id"} element={<About/>}/>   <!--这里会有参数并且是通过id接收-->3.组件获取import {useParams   <!--获取路由传参的方法-->} from 'react-router-dom';const params=useParams();console.log(params.id); <!--{}-->路由传参第二种方式(useSearchParams):1. <NavLink to={"/about?a=1&b=2"}>About</NavLink>  <!--传了两个参数 a,b-->2. <Route path={"/about"} element={<About/>}/>3.获取参数import {useSearchParams} from 'react-router-dom';const [search]=useSearchParams();console.log(search.get("a"));  <!--通过get方法获取指定参数-->
import {// useParams,  //获取路由传参的方法useSearchParams
} from 'react-router-dom';const About=()=> {// const params=useParams();// console.log(params.name);const [search,setSearch]=useSearchParams();console.log(search.get("a"));console.log(search); //{size:2} 遍历出来search.forEach((v,i)=>{console.log(i,v)})return (<h2>About</h2>)
}export default About;

路由跳转(Hook:useNavigate)

React跳转(useNavigate):(在Vue中,push() 会产生历史记录,replace() 不会产生历史记录)import {useNavigate} from "react-router-dom";const navigate=useNavigate();navigate("/home/home2");  <!--这种页面跳转相当于添加了一条历史记录-->navigate("/home/home2",{replace: true});  <!--这种页面跳转相当于替换掉了一条历史记录-->navigate(-1)  <!--返回 -1:上一页,0:当前页,1:下一页-->
import {useNavigate} from "react-router-dom";const Home1=()=>{const navigate=useNavigate();const goHome2=()=> {// navigate("/home/home2");  //这种页面跳转相当于添加了一条历史记录navigate("/home/home2",{replace: true});  //这种页面跳转相当于替换掉了一条历史记录}return (<div><h2>Home1</h2><button onClick={goHome2}>跳到Home2</button></div>)
}export default Home1;
import {useNavigate} from "react-router-dom";const Home2=()=>{const navigate=useNavigate();const goBack=()=>{navigate(-1)}return (<div><h2>Home2</h2><button onClick={goBack}>返回</button></div>)
}export default Home2;

路由的构建

src\index.js

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

src\App.js

import './App.css';
import Routers from './router'function App() {return (<div className="App"><Routers/></div>);
}export default App;

router\index.js

import {useRoutes,Navigate,
} from 'react-router-dom'
import Power from "./power"; //进行权限判断处理import Home from '../pages/home'
import Login from '../pages/login'
import Admin from '../pages/home/admin'
import Notice from "../pages/home/notice"
import Student from "../pages/home/student"//路由配置的组件
const Routers=()=>{return useRoutes([{path:'/',element:<Navigate to={"/login"}/>},{path:'/login',element:<Login/>},{path:'/home',// element:<Home/>,// element:Power(<Home/>,"/home"), /*高阶函数*/element:<Power path='/home' ele={<Home/>}/>, /*高阶组件*/children:[            /*子路由*/{index:"index", /*默认展示当前的子组件*/// path:'admin', /*子路由不需要 /admin 这样写,斜杠不需要*/element:<Power path='/home/notice' ele={<Notice/>}/>},{path:'notice',element:<Power path='/home/notice' ele={<Notice/>}/>},{path:'student',element:<Power path='/home/student' ele={<Student/>}/>},{path:'admin',element:<Power path='/home/admin' ele={<Admin/>}/>}]}])}export  default Routers;

router\power.js 高阶组件

const Power=(props)=>{console.log("Power执行")  //避免多次重复执行,在router中应写作组件<power/>,而不是直接调用Power()console.log(props)//这里拦截判断是否可以返回当前组件//取出sessionStorage中的power比对,如果本地数据中有就返回当前组件,如果本地用户数据中没有就不返回当前组件let power=JSON.parse(sessionStorage.getItem("power")); //[{},{},{}]for(let i=0;i<power.length;i++){if(power[i].link.indexOf(props.path)!==-1){  //有权限访问return <>{props.ele}</>}}return <div><h1>没有权限</h1></div>;  //循环完了都没找到有的话,就是没有权限}export default Power;

权限拦截:

现在的路由是拦截到请求,直接返回对应的组件,实际上应该先查看用户是否有权限访问需要写一个函数,接收一个组件为参数。如果有权限,就返回组件;如果没有权限就返回登录或者错误组件{path:'/home',// element:<Home/>,    -------以前直接返回组件element:Power(<Home/>),   -------把组件转入Power函数,在函数内部进行逻辑判断,最后根据权限返回需要展示的组件}element:Power(<Home/>)   -------向一个函数传递一个组件作为参数,我们称为高阶组件,函数负责逻辑代码,组件负责页面展示高阶组件,源于高阶函数,高阶函数就是把函数A作为参数传给函数B,调用函数B返回一个新的函数C<script>function HOF(fn){  //函数Breturn function(){  //函数Cfn()}}let myFn=HOF(()=>{  //函数Aconsole.log("哈哈哈哈")})myFn();</script>高阶组件HOC,向一个函数A传递一个组件C作为参数,最后返回一个新的组件(使用高阶组件的目的,为了组件的二次加工,或者功能逻辑判断)项目启动后,路由中的Power函数会被执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flowable7.x学习笔记(十)分页查询已部署 BPMN XML 流程

前言 上一篇文章我们已经完成了流程的部署功能&#xff0c;那么下一步就是要激活流程了&#xff0c;但是我们要需要明确的指定具体要激活部署后的哪一条流程&#xff0c;所以我们先把已部署的基础信息以及具体定义信息分页查询出来&#xff0c;本文先把基础代码生成以及完成分页…

【论文阅读23】-地下水预测-TCN-LSTM-Attention(2024-11)

这篇论文主要围绕利用深度学习模型检测地下水位异常以识别地震前兆展开。 [1] Chen X, Yang L, Liao X, et al. Groundwater level prediction and earthquake precursor anomaly analysis based on TCN-LSTM-attention network[J]. IEEE Access, 2024, 12: 176696-176718. 期刊…

electron从安装到启动再到打包全教程

目录 介绍 安装 修改npm包配置 执行安装命令 源代码 运行 打包 先安装git, 安装打包工具 导入打包工具 执行打包命令 总结 介绍 electron确实好用,但安装是真的要耗费半条命。每次安装都会遇到各种问题,然后解决了之后。后面就不需要安装了,但有时候比如电脑重装…

【Rust 精进之路之第4篇-数据基石·上】标量类型:整数、浮点数、布尔与字符的精妙之处

系列&#xff1a; Rust 精进之路&#xff1a;构建可靠、高效软件的底层逻辑 作者&#xff1a; 码觉客 发布日期&#xff1a; 2025-04-20 引言&#xff1a;构成万物的“原子”——标量类型 在上一篇文章【变量观】中&#xff0c;我们深入探讨了 Rust 如何通过 let、mut、const…

消息中间件RabbitMQ:简要介绍及其Windows安装流程

一、简要介绍 定义&#xff1a;RabbitMQ 是一个开源消息中间件&#xff0c;用于实现消息队列和异步通信。 场景&#xff1a;适用于分布式系统、异步任务处理、消息解耦、负载均衡等场景。 比喻&#xff1a;RabbitMQ 就像是快递公司&#xff0c;负责在不同系统间安全快速地传递…

Docker概念详解

文章目录 一、Docker&#xff1a;容器化应用的基石1.1 环境1.2 Docker 是什么1.3 Docker镜像1.3.1 基础镜像(Base Image)1.3.2 Dockerfile1.3.3 容器镜像&#xff08;Container Image&#xff09; 1.4 Registry1.5 容器1.6 Docker VS 虚拟机 二、Docker 的架构原理2.1 C/S软件架…

linux查看及修改用户过期时间

修改用户有效期 密码到期时间 sudo chage -E 2025-12-31 username sudo chage -M 180 username sudo chage -d $(date %F) username 查询用户密码到期时间 for user in $(cat /etc/passwd |cut -d: -f1); do echo $user; chage -l $user | grep "Password expires"; …

CGAL 计算直线之间的距离(3D)

文章目录 一、简介二、实现代码三、实现效果一、简介 这里的计算思路很简单: 1、首先将两个三维直线均平移至过原点处,这里两条直线可以构成一个平面normal。 2、如果两个直线平行,那么两条直线之间的距离就转换为直线上一点到另一直线的距离。 3、如果两个直线不平行,则可…

<项目代码>YOLO小船识别<目标检测>

项目代码下载链接 YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0…

基于RK3588+FPGA+AI YOLO全国产化的无人船目标检测系统(二)平台设计

基于项目需求确定国产 AI 平台的总体架构设计&#xff0c;完成硬件单元的选择和搭建以及开发工具链的配置工作。 4.1 国产 AI 平台总体架构 本文设计了一套灵活高效的国产 AI 平台总体架构&#xff0c;设计方法是在嵌入式平 台上使用串行总线&#xff08; Peripheral Co…

Typescript中的泛型约束extends keyof

概要 本文主要分享Typescript中泛型约束的使用方法。在开发过程中&#xff0c;通过使用该方法&#xff0c;可以在编译阶段&#xff0c;帮助我们查找到一些潜在的空值引用错误。 代码和实现 我们预先定义了IUser接口&#xff0c;接口包括了id&#xff0c;姓名&#xff0c;性别…

C++ 2025 展望:现代编程需求与新兴技术驱动下的变革

C 作为一门成熟的语言&#xff0c;在多个领域&#xff08;嵌入式系统、高性能计算、图形渲染、游戏开发等&#xff09;依旧占据重要地位。在 2024 年&#xff0c;C 开发继续在许多传统领域保持强劲的势头&#xff0c;同时也面临着新的挑战与发展方向。展望 2025 年&#xff0c;…

包管理工具有哪些?主流软件分享

常见的包管理工具主要有&#xff1a;npm、Yarn、pnpm、Composer、Maven、pip、Conda 等&#xff0c;其中 npm 是目前全球使用最广泛的JavaScript包管理工具&#xff0c;以丰富的生态、便捷的使用体验以及强大的社区支持闻名。npm具备依赖管理、版本控制、脚本执行等强大功能&am…

2025年世界职业院校技能大赛实施方案(意见稿)

为贯彻落实《教育强国建设规划纲要&#xff08;2024—2035年&#xff09;》&#xff0c;进一步提升世界职业院校技能大赛&#xff08;以下简称“大赛”&#xff09;内涵质量&#xff0c;发挥大赛引领作用&#xff0c;提升高技能人才培养质量&#xff0c;服务现代职业教育体系建…

Redis 慢查询分析与优化

Redis 慢查询分析与优化 参考书籍 &#xff1a; https://weread.qq.com/web/reader/d5432be0813ab98b6g0133f5kd8232f00235d82c8d161fb2 以下从配置参数、耗时细分、分析工具、优化策略四个维度深入解析 Redis 慢查询问题&#xff0c;结合实战调优建议&#xff0c;帮助开发者…

AI之pdf解析:Tesseract、PaddleOCR、RapidPaddle(可能为 RapidOCR)和 plumberpdf 的对比分析及使用建议

目录标题 Tesseract、PaddleOCR、RapidPaddle&#xff08;可能为 RapidOCR&#xff09;和 plumberpdf 的对比分析1. Tesseract类型: 开源 OCR 引擎特点:缺点:适用场景: 2. PaddleOCR (推荐)类型:特点:缺点:适用场景: 复杂版式文档、多语言混合文本、需要高精度识别的场景&#…

算法 | 成长优化算法(Growth Optimizer,GO)原理,公式,应用,算法改进研究综述,matlab代码

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 成长优化算法 一、算法原理二、核心公式三、应用领域四、算法改进研究五…

网络原理(TCP协议—协议格式,性质(上),状态)

目录 1.TCP协议段格式。 2.TCP协议传输时候的性质。 2.1确认应答。 2.2超时重传。 2.3连接管理。 2.3.1 三次握手。 2.3.2四次挥手。 3.TCP常见的状态。 1.TCP协议段格式。 TCP协议段是由首部和数据两部分构成的。首部包含了TCP通信所需要的各种控制信息&#xff0c;而…

XAML 标记扩展

# XAML 标记扩展详解 标记扩展(Markup Extensions)是XAML中一种特殊的语法结构&#xff0c;允许在XAML属性中嵌入动态值或引用&#xff0c;而不是简单的静态值。它们使用花括号{}作为标识&#xff0c;是XAML强大功能的核心组成部分。 ## 基本语法结构 所有标记扩展都遵循以下…

DeepSeek+Cursor+Devbox+Sealos项目实战

黑马程序员DeepSeekCursorDevboxSealos带你零代码搞定实战项目开发部署视频教程&#xff0c;基于AI完成项目的设计、开发、测试、联调、部署全流程 原视频地址视频选的项目非常基础&#xff0c;基本就是过了个web开发流程&#xff0c;但我在实际跟着操作时&#xff0c;ai依然会…