欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 【React】路由器 React-Router

【React】路由器 React-Router

2025/4/20 12:57:23 来源:https://blog.csdn.net/qq_57567877/article/details/147131571  浏览:    关键词:【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函数会被执行

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词