react路由封装

x33g5p2x  于5个月前 转载在 React  
字(6.8k)|赞(0)|评价(0)|浏览(194)

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

//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

functionApp() {
  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 内容

/** @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,导入路由列表 ,循环导入路由方法(判断该页面是否需要锻炼)

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"

functionApp() {
  return(
    <>{/*这里Suspense是用于和React.lazy配合使用的 */}
      <Suspense fallback={<Loading />}>
        <Routes>{/*循环路由 */}
          {loopRouter(routesList)}
          {/*找不到自己定义的根路由,默认跳转到 */}
          <Route path="*" element={<Navigate to='/NotFound' replace={true} />} />
        </Routes>
      </Suspense>
    </>
)
}

export default App

App.js

2.5全局路由封装

router文件夹下,创建index.js(路由列表),创建loopRouter.js (路由循环添加到页面)

路由列表:index.js
参数名介绍
path链接路径
component对应的页面地址
exact是否严格匹配
children子路由,嵌套路由列表
indexindex属性来指定默认路由, path需要为空,

注:indexchildren嵌套路由的第一个页面需要添加index参数为true。然后path参数为空。

index相当于vue的redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向。

children子路由页面使用

/** @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

/** @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

/** @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 defaultclass 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

.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

本文来自博客园,作者:虚乄,转载请注明原文链接:https://www.cnblogs.com/lovejielive/p/17641195.html

相关文章