0
点赞
收藏
分享

微信扫一扫

❤React-ReactRouter路由的使用

❤React-ReactRouter路由的使用

React Router 在 2021 年 11 月份的时候更新 v6 的版本,本次主要学习的也是v6,里面更改了很多新写法特性!

1、路由的认识

官网给他定义是一个库,不是一个框架。

React官方并没有提供路由库,路由插件,而是推荐我们使用React结合ReactRouter来进行路由的映射。

正常的路由开发模式分为以下三种:

  • 编程式路由:自己在页面中写代码进行路由编程,包括映射、路由引入。
  • 配置式路由:将路由映射写到配置文件中,剩下的就是自动渲染。
  • 约定式路由:无需配置路由,你的项目文件系统就是路由。(Next就是这种方式)

先来看看Vuejs配置式路由:

src/router/index.js

import VueRouter from vue-router
import Login from ./Login.vue

const routes = [
{
path:/login,
name:Login
component:Login
}
]
const router = new VueRouter({
routes,
mode:hash
})

export default router

2、路由安装下载

下载React路由

yarn add react-router-dom

3、路由的使用

我们先在App.jsx 组件搭建路由(四个页面主要是后台首页、登陆页面、后台文章、后台用户)

App.jsx之中引入页面


import Home from '@/pages/Home';
import Login from '@/pages/Login';
import User from '@/pages/User';
import Article from '@/pages/Article';

App.jsx之中路由的引入和使用

import { BrowserRouter, Routes, Route } from react-router-dom

<BrowserRouter>
{/* 路由映射列表 */}
<Routes>
{/* 路由具体路径匹配 */}
<Route path=/ element={<Home></Home>}></Route>
<Route path=/login element={<Login></Login>}></Route>
<Route path=/user element={<User></User>}></Route>
<Route path=/article element={<Article></Article>}></Route>
</Routes>
</BrowserRouter>

4、路由详细说明:

路由大致认识

路由器目前有两种(:BrowserRouter、HashRouter),决定了当前路由的模式。

BrowserRouter:默认采用history模式

HashRouter:采用hash模式。路径访问的时候需要/#/

路由映射:Routes、Route主要负责进行路由路径匹配,提供渲染的组件

Routes:表示可以包含多个映射规则。从上到小的进行匹配。当匹配成功结束匹配

Route:进行路由映射,path路由路径,element提供映射组件。指定的这个地方渲染组件

路由导航:Link、NavLink

通过Link和NavLink组件可以实现路由的切换,类似于Vue之中的router-link进行对号入座!

路由映射规则

默认索引和重定向 需求:当我们点击进来以后首先进入的是我们的home主页面:index 的作用

默认进来匹配的组件就是Home组件。默认索引。index只能用一次

<Routes>
<Route path=/ index element={<Home></Home>}></Route>
</Routes>

重定向规则

import {Navigate} from react-router-dom

<Routes>
<Route path=/ element={<Navigate to=/login></Navigate>}></Route>
</Routes>

我们还可以用重定向解决404的问题

完整页面大致如下:

import AntdComp from ./components/AntdComp;
import Header from ./components/Header;
import Login from ./views/Login;
import Register from ./views/Register;
import ForgetPassword from ./views/ForgetPassword;
import { Button, ConfigProvider, Space } from 'antd';
import NotFind from ./views/NotFind;
import { BrowserRouter,HashRouter, Routes, Route,Link,NavLink,Navigate } from react-router-dom
function App() {
return (
<ConfigProvider
theme={{
token: {
// Seed Token,影响范围大
colorPrimary: '#7cb305'
},
}}
>

{/* 路由器 */}
<BrowserRouter>
{/* 路由映射列表 */}
<ul>
<li>
<Link to=/register>注册</Link>
</li>
<li>
<NavLink to=/forget>忘记密码</NavLink>
</li>
</ul>
<Routes>
{/* 路由具体路径匹配 */}
<Route path=/ element={<Navigate to=/login></Navigate>}></Route>
<Route path=/login element={<Login></Login>}></Route>
<Route path=/register element={<Register></Register>}></Route>
<Route path=/forget element={<ForgetPassword></ForgetPassword>}></Route>
<Route path=/404 element={<NotFind></NotFind>}></Route>
<Route path=* element={<Navigate to=/404></Navigate>}></Route>
</Routes>
</BrowserRouter>
</ConfigProvider>

);
}

export default App;

5、路由组件的封装

根组件下面新建文件夹router=>index.tsx ,这个文件夹下面就专门负责我们的路由

接下来我们把路由给拿出来单独放到一文件夹里面

import { lazy } from 'react'; //lazy懒加载
import { BrowserRouter, Routes, Route } from 'react-router-dom';


import Home from '@/pages/Home';
import Login from '@/pages/Login';
import User from '@/pages/User';
import Article from '@/pages/Article';

function getRouter() {
return <>
<BrowserRouter>
{/* 路由映射列表 */}
<Routes>
{/* 路由具体路径匹配 */}
<Route path=/ index element={<Home></Home>}></Route>
<Route path=/login element={<Login></Login>}></Route>
<Route path=/user element={<User></User>}></Route>
<Route path=/article element={<Article></Article>}></Route>
</Routes>
</BrowserRouter></>

}
export default getRouter

6、重定向路由redirect(Navigate)

接下来我们输入http://localhost:3000/a 却发现一片空白,那么我们想要输入不匹配的直接跳转到我们的首页应该如何做呢

先看看之前v5版本的重定向如何做的

在我们访问'/' 的时候直接就重定向到了‘/filems’ 这个路由

在这里确实遇到了坑,就是写的完全一样,但是就是不生效,前端瞬息万变,强烈建议有些东西看看会了就行,记住了也没啥用,最重要的就是理解并且会查阅相关的文档,这里新版本的v6写法已经变成了下面这样子:(含义就是高改变了以后 v6 中的重定向更加简洁和直观)

主要是利用其中的Navigate 进行冲定向

import { BrowserRouter as Router, Routes, Route ,Navigate} from 'react-router-dom';


{/* 假设需要在某个条件下进行重定向 */}
<Route path=/article element={<Navigate to=/new-url />} />

{/* 或者根据条件返回一个 Navigate 组件 */}
<Route path=/another-old-url element={<User></User>} />

{/* 其他路由 */}
<Route path=/new-url element={<User></User>} />

所以当我们访问/article 会自动重新定向去 /new-url 地址,展示User组件

7、404 界面

当我们找不到未匹配的路径的时候,我们现在的页面一片空白,接下来我们想找不到页面的时候去我们的404界面,应该怎么做呢

新建一个NotFind.tsx 界面,这里也是巧妙的利用我们的Navigate的功能

<Route path=/404 element={<NotFind></NotFind>}></Route>
<Route path=* element={<Navigate to=/404></Navigate>}>

访问http://localhost:3000/8888地址,自动重定向到了我们的404界面

8、React.lazy 优化路由

认识

我们发现加了路由以后我们的加载缓慢了很多,React.lazy可以减少我们应用的初始加载时间,提升用户体验,对于大型单页应用(SPA)或需要优化加载时间的应用特别有用

React.lazy 是 React 提供的一个动态导入组件的方法,作用是需要时才加载组件,而不是在应用初始化时就加载所有组件,从而提高应用的性能和加载速度。

React.lazy 函数接受一个函数作为参数,动态导入组件。当组件需要被渲染时,React 将调用这个函数来加载组件。加载完成后,组件将被缓存,以便在将来的渲染中重用。

React.lazy 结合 Suspense 组件使用时,可以优雅地处理动态加载组件时的 loading 状态,使代码更加清晰和易于维护。

使用lazy,优化我们的router.tsx

const Home = lazy(() => import('@/pages/Home'));
const Login = lazy(() => import('@/pages/Login'));
const NotFind = lazy(() => import('@/pages/NotFind'));

9、使用Suspense 默认加载效果

v6之前的版本使用

// App.js
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Login = lazy(() => import('./Login'));
const Admin = lazy(() => import('./Admin'));

const App = () => {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path=/ component={Login} />
<Route path=/admin component={Admin} />
</Switch>
</Suspense>
</Router>

);
};

export default App;

v6版本对此作了一些调整

// App.js
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Login = lazy(() => import('./Login'));
const Admin = lazy(() => import('./Admin'));

const App = () => {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path=/ element={<Login />} />
<Route path=/admin element={<Admin />} />
</Routes>
</Suspense>
</Router>

);
};
export default App;

刷新页面看看我们的加载效果

10、嵌套路由 Link和 Outlet的使用

接下来我们在文章之中添加两个种类的文章类型,点击的时候跳转进入对应的界面,但是前面的Article依然不进行改变

分别是访问Article的时候进入Article, 问Article/Articletype1的时候进入Article/Articletype1, 问Article/Articletype2的时候进入Article/Articletype2,

一级页面文章 Article.js

// Article.js 
import React from 'react';
import { Link, Outlet } from 'react-router-dom';

const Article = () => {
return (
<div>
Article Page
<nav>
<Link to=Articletype1>Article Type 1</Link>{' '}
<Link to=Articletype2>Article Type 2</Link>
</nav>
<Outlet />
</div>

);
};

export default Article;

文章类型页面组件(二级路由)

ArticleType1.js

// ArticleType1.js
import React from 'react';

const ArticleType1 = () => {
return <div>Article Type 1 Page</div>;
};

export default ArticleType1;

ArticleType2.js

// ArticleType2.js
import React from 'react';

const ArticleType2 = () => {
return <div>Article Type 2 Page</div>;
};

export default ArticleType2;

设置路由

导入

//导入
const ArticleType1 = lazy(() => import('@/views/article/Articletype1'));
const ArticleType2 = lazy(() => import('@/views/article/Articletype2'));

配置

//配置
<Route path=/Article element={<Article />}>
<Route path=Articletype1 element={<ArticleType1 />} />
<Route path=Articletype2 element={<ArticleType2 />} />
</Route>

接下来我们尝试一下访问Article:

点击对应的部分已经展示:

已经成功实现!

11、Link 改成编程式路由的方式进行跳转

之前我们文章的跳转采用的是Link的方式,现在我们改写成为这种编程式路由的方式进行跳转

import { Link, Outlet,useNavigate} from 'react-router-dom';

<a rel=nofollow href=# onClick={(e)=>{tiao1(e)}}>Article Type 1</a>

const tiao1=(e:any)=>{
e.preventDefault();
navigate('/articletype1')
}

结果我们点击,奇怪,怎么跳转到了404 呢

其实我们正确的地址应该是 '/article/articletype1'

更改以后进行尝试:

  const tiao1=(e:any)=>{
e.preventDefault();
navigate('/article/articletype1')
}
const tiao2=(e:any)=>{
e.preventDefault();
navigate('/article/articletype2')
}

更改方式成功!

12、接下来在我们的后台实现一下管理部分的二级菜单效果admin(NavLinkLink)

想要的布局效果大致如下:

  • Link:Link 用于定义导航链接,但不提供样式控制。它是一个简单的 HTML <a> 标签的封装,用于在不刷新页面的情况下进行页面跳转。
  • NavLink:NavLinkLink 的增强版,它可以为当前页面匹配的链接添加活动状态(active state),通常用于设置导航链接的样式以显示当前页面或路由的状态。你可以根据路由匹配情况添加自定义的类名或样式。

需要为导航链接添加样式以反映当前页面或路由的活动状态,那么建议使用 NavLink

只是需要简单的导航链接而不需要活动状态的样式控制,使用 Link 就可。

我们文章之中使用了Link,这里我们菜单使用 NavLink

之前我们都是这么写的:

{/* NavLink */} 
<NavLink to=/ activeClassName=active>Home</NavLink>
<NavLink to=/about activeClassName=active>About</NavLink>

结果在v6一写直接报错: 果然,这货在v6之中更改了写法,果然一步一个坑啊

v6版本之中路由更改成了下面的写法:

let activeClassName = underline
<NavLink
to=/faq
className={({ isActive }) =>
isActive ? activeClassName : undefined
}
>
FAQs
</NavLink>

来看看匹配时候我们的路由

13、完善一下我们的路由:


import AntdComp from ./components/AntdComp;
import Header from ./components/Header;
import Login from ./views/Login;
import Register from ./views/Register;
import ForgetPassword from ./views/ForgetPassword;
import { Button, ConfigProvider, Space } from 'antd';
import NotFind from ./views/NotFind;
import Home from ./views/Home;
import User from ./views/subs/User;
import Role from ./views/subs/Role;
import { BrowserRouter, HashRouter, Routes, Route, Link, NavLink, Navigate } from react-router-dom
function App() {
return (
<ConfigProvider
theme={{
token: {
// Seed Token,影响范围大
colorPrimary: '#7cb305'
},
}}
>

{/* 路由器 */}
<BrowserRouter>
{/* 路由映射列表 */}
<ul>
<li>
<Link to=/register>注册</Link>
</li>
<li>
<NavLink to=/forget>忘记密码</NavLink>
</li>
</ul>
<Routes>
{/* 路由具体路径匹配 */}
<Route path=/ element={<Navigate to=/login></Navigate>}></Route>
<Route path=/login element={<Login></Login>}></Route>
<Route path=/home element={<Home></Home>}>
<Route index element={<User></User>}></Route>
<Route path=role element={<Role></Role>}></Route>
</Route>
<Route path=/register element={<Register></Register>}></Route>
<Route path=/forget element={<ForgetPassword></ForgetPassword>}></Route>
<Route path=/404 element={<NotFind></NotFind>}></Route>
<Route path=* element={<Navigate to=/404></Navigate>}></Route>
</Routes>
</BrowserRouter>
</ConfigProvider>

);
}

export default App;

在Home下面配置路由渲染出口

import React from 'react'
import { Outlet, Link } from react-router-dom

export default function Home() {
return (
<div style={{ display: flex }}>
<div style={{ width: 200px, backgroundColor: pink }}>
<ul>
<li>
<Link to=/home/user>用户</Link>
</li>
<li>
<Link to=/home/role>角色</Link>
</li>
</ul>
</div>
<div>
<h3>content</h3>
<Outlet></Outlet>
</div>
</div>

)
}

检查一下我们的路由,完美实现!

举报

相关推荐

0 条评论