router v6 路由统一管理与添加,对是否登录进行判断。
1.使用脚手架创建项目
新建一个文件夹 ,在文件夹内部打开命令行工具。
执行命令:npx create-react-app 项目名字
将项目放在开发工具中,打开项目终端运行项目(npm start / yarn start)
注:npx命令会帮助我们临时安装create-react-app包,然后初始化项目,完成之后会自动删除,不需要全局安装create-react-app。
1.1创建完成项目-目录
1.2 对项目目录进行简化
src保留App.js , index.css , index.js,其他的可以删除
修改index.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// React: 框架的核心包 import React from 'react'; // ReactDOM: 专门做渲染相关的包 import ReactDOM from 'react-dom/client'; // 应用全局样式文件 import './index.css'; // 引入根组件 import App from './App'; // 渲染根组件App 到一个id为root的DOM节点上 const root = ReactDOM.createRoot(document.getElementById('root')); root.render( //严格模式节点,useEffect执行机制 <React.StrictMode> <App /> </React.StrictMode> );index.js
修改App,js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function App() { return ( <div className="App"> APP页面 </div> ); } export default App;App.js
运行结果
2.React-Router V6使用
安装插件
npm i react-router-dom -S
目前React Router v6是React Router的最新版本,所以安装就是v6。
2.1导入react-router-dom 修改index.js 内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* * @description: * @Author: Jay * @Date: 2023-08-18 14:32:46 * @LastEditors: Jay * @LastEditTime: 2023-08-18 14:48:22 */ // React: 框架的核心包 import React from 'react'; // ReactDOM: 专门做渲染相关的包 import ReactDOM from 'react-dom/client'; // 应用全局样式文件 import './index.css'; // 引入根组件 import App from './App'; // 路由 import { BrowserRouter } from 'react-router-dom' // 渲染根组件App 到一个id为root的DOM节点上 const root = ReactDOM.createRoot(document.getElementById('root')); /* ! 去掉严格模式 页面不会加载2次 */ root.render( <BrowserRouter> <App /> </BrowserRouter> ); /* ! 严格模式 页面会加载2次 */ // root.render( // //严格模式节点,useEffect执行机制 // <React.StrictMode> // <BrowserRouter> // <App /> // </BrowserRouter> // </React.StrictMode> // );index.js
注:在严格模式下,React 的开发环境会刻意执行两次渲染,用于突出显示潜在问题。
StrictMode
是一个用来突出显示应用程序中潜在问题的工具。
2.2 创建项目其他文件夹
文件夹名字 | 介绍 |
---|---|
components | 全局组件 |
router | 路由管理 |
assets | 静态文件 |
utils | 全局js |
views | 项目页面 |
整个文件目录是以vue形式创建的。有些不太明白的可自行百度 vue目录结构解析,components,router,assets,view有详细的介绍。utils是开发者个人的定义。
2.3 React-Router V6版本常用路由
组件名 | 作用 | 说明 |
---|---|---|
<Routers> |
一组路由 | 代替原有<Switch> ,所有子路由都用基础的Router children来表示 |
<Router> |
基础路由 | Router是可以嵌套的,解决原有V5中严格模式,后面与V5区别会详细介绍 |
<Link> |
导航组件 | 页面中跳转使用 |
<Outlet/> |
自适应渲染组件 | 二级路由渲染组件 |
2.4 全局路由导入
修改App.js,导入路由列表 ,循环导入路由方法(判断该页面是否需要锻炼)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import React, { Suspense } from 'react' import { Route, Routes, Navigate } from 'react-router-dom' // 加载动画 组件 import Loading from './components/loading/loading' //路由列表 import routesList from './router/index' //循环路由 import { loopRouter } from "./router/loopRouter" function App() { return ( <> {/* 这里Suspense是用于和React.lazy配合使用的 */} <Suspense fallback={<Loading />}> <Routes> {/* 循环路由 */} {loopRouter(routesList)} {/* 找不到自己定义的根路由,默认跳转到 */} <Route path="*" element={<Navigate to='/NotFound' replace={true} />} /> </Routes> </Suspense> </> ) } export default AppApp.js
2.5全局路由封装
router文件夹下,创建index.js(路由列表),创建loopRouter.js (路由循环添加到页面)
路由列表:index.js
参数名 | 介绍 |
---|---|
path | 链接路径 |
component | 对应的页面地址 |
exact | 是否严格匹配 |
children | 子路由,嵌套路由列表 |
index | index属性来指定默认路由, path需要为空, |
注:index为children嵌套路由的第一个页面需要添加index参数为true。然后path参数为空。
index相当于vue的redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向。
children子路由页面使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* * @description: 路由列表 * @Author: Jay * @Date: 2023-08-18 15:25:28 * @LastEditors: Jay * @LastEditTime: 2023-08-18 15:39:40 */ import { lazy } from 'react' const routesList = [ // 首页 { path: '/', component: lazy(() => import('../views/Home/Home.js')), exact: true, meta: { title: '首页', //是否需要登录 requireAuth: false } }, // 登录 { path: '/LogIn', component: lazy(() => import('../views/LogIn/LogIn.js')), exact: true, meta: { title: '登录', //是否需要登录 requireAuth: false } }, //二级路由 { path: "/Basis", // 使用懒加载的方法 component: lazy(() => import("../views/Basis/Basis.js")), // 如果要求严格路径 exact: true, //子路由 children: [ { path: "", // index属性来指定默认路由 path需要为空 index: true, component: lazy(() => import("../views/BasisLevel/BasisLevel.js")), exact: false, meta: { title: '二级路由1', //是否需要登录 requireAuth: true } }, { path: "BasisLevel2", component: lazy(() => import("../views/BasisLevel2/BasisLevel2.js")), exact: false, meta: { title: '二级路由2', //是否需要登录 requireAuth: true } } ] }, //404页面 { path: '/NotFound', exact: false, component: lazy(() => import('../views/NotFound/NotFound.js')), meta: { title: '404', //是否需要登录 requireAuth: false } } ] export default routesList;index.js
循环路由 loopRouter.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* * @description: 路由循环 添加到页面 * @Author: Jay * @Date: 2023-08-18 15:25:38 * @LastEditors: Jay * @LastEditTime: 2023-08-18 15:25:46 */ import { Route, Navigate } from 'react-router-dom' /* ----遍历一级路由----*/ const loopRouter = (routerList) => { return routerList.map((item) => { const { path, exact, children } = item; return <Route key={path} exact={exact} path={path} element={<DomTitle item={item}> </DomTitle>} > {/* 遍历二级路由 有些页面没有二级 所以默认为空 [] */} {SecondRouter(children || [])} </Route >; }); }; /* ----遍历二级路由----*/ const SecondRouter = (children) => { return children.map(i => { return <Route key={i.path} exact={i.exact} path={i.path} index={i.index} element={<DomTitle item={i}></DomTitle>} /> }) } /* ----设置页面标题----*/ const DomTitle = ({ item }) => { const { meta } = item document.title = meta?.title || ''; return meta?.requireAuth ? <RequireAuth item={item} /> : <item.component /> } /* ---- 判断是否需要登录 ----*/ const RequireAuth = ({ item }) => { // const token = sessionStorage.getItem('Authorization') const token = '已登录' if (token === null || token === '') { return <Navigate to='/LogIn' replace={true} /> } else { return <item.component /> } } export { loopRouter, RequireAuth }loopRouter.js
3.加载动画
components文件夹里创建loading文件夹
创建loading.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* * @description: 加载动画 组件 * @Author: Jay * @Date: 2022-12-06 09:39:25 * @LastEditors: Jay * @LastEditTime: 2023-08-18 13:49:58 */ import { Component } from "react"; import "./loading.css" export default class Loading extends Component { render() { return ( // 加载动画 <div className="container_nomount"> <div className="loading"> <span></span> <span></span> <span></span> <span></span> <span></span> </div> <h2>Loading...</h2> </div> ); } }loading.js
创建loading.css
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
.container_nomount { display: flex; justify-content: center; align-items: center; flex-direction: column; box-sizing: border-box; position: fixed; width: 100%; height: 100%; overflow: hidden; font-family: 'Poppins', sans-serif; } .container_nomount h2 { margin-top: 20px; font-size: 1.5em; margin-block-start: 0.83em; margin-block-end: 0.83em; margin-inline-start: 0px; margin-inline-end: 0px; font-weight: bold; } .container_nomount .loading { width: 80px; height: 40px; margin: 0 auto; margin-top: -40px; } .container_nomount .loading span { display: inline-block; width: 8px; height: 100%; border-radius: 4px; background: #1890ff; animation: load 1s ease infinite; } @keyframes load { 0%, 100% { height: 40px; background: #ff3378; } 50% { height: 70px; margin: -15px 0; background: #1890ff; } } .container_nomount .loading span:nth-child(2) { animation-delay: 0.2s; } .container_nomount .loading span:nth-child(3) { animation-delay: 0.4s; } .container_nomount .loading span:nth-child(4) { animation-delay: 0.6s; } .container_nomount .loading span:nth-child(5) { animation-delay: 0.8s; }loading.css
项目地址:https://github.com/jielov/react-loop-router
标签:index,封装,App,js,react,import,路由 From: https://www.cnblogs.com/lovejielive/p/17641195.html