0
点赞
收藏
分享

微信扫一扫

【react+ts】react使用react-router-dom动态生成路由-03

大师的学徒 2022-02-09 阅读 131

在这里插入图片描述

1.index.tsx存放项目路由

import React,{lazy} from "react";
import RouterInterface from "@/router/routerInterface";
//lazy懒加载路由,按需加载视图
const Login = lazy(() => import("@/views/v1/login/Login"));
//普通用户
const UserOperation = lazy(()=>import('@/views/v1/userOperation/UserOperation'));//用户操作界面

//内部人员
// 预约管理
const ReservationList = lazy(()=>import('@/views/v1/reservation/reservationList/ReservationList'));//预约列表

const NotFindPage = lazy(()=>import('@/components/v1/common/error/404'));
const ServerError = lazy(()=>import('@/components/v1/common/error/500'));
const NoPowerPage = lazy(()=>import('@/components/v1/common/error/403'));


const routes: RouterInterface[] = [
    {
        key: 0,
        pageName: 'login',
        path: '/login',
        name: '登录',
        nameArr:[],
        component: <Login/>,
        isAuth: false,
        isShow:true,
    },
    {
        key: 1,
        path: '/userOperation',
        name: '用户界面',
        nameArr:[],
        isAuth: true,
        component: <UserOperation/>,
        isShow:true,
    },
    {
        key: 2,
        path: '/reservation',
        name: '预约管理',
        nameArr:[],
        isAuth: true,
        isShow:true,
        routes: [
            {
                key: 2,
                path: '/reservation/reservationList/ReservationList',
                name: '预约列表',
                nameArr: ['预约管理','预约列表'],
                component:<ReservationList/>,
                isAuth: true,
                isShow:true
            }
        ]
    },
    {
        key: 44,
        path: '/404',
        pageName: 'error',
        name: '找不到页面',
        nameArr:[],
        isAuth: false,
        component: <NotFindPage/>,
        isShow:false
    },
    {
        key: 45,
        path: '/403',
        pageName: 'error',
        name: '你没有此页面的访问权限',
        nameArr:[],
        isAuth: false,
        component: <NoPowerPage/>,
        isShow:false
    },
    {
        key: 46,
        path: '/500',
        pageName: 'error',
        name: '服务器发生了错误',
        nameArr:[],
        isAuth: false,
        component: <ServerError/>,
        isShow:false
    }
];

export {routes};

2.routerGuard.tsx路由导航

import React, {FC, useEffect, useState} from 'react';
import {Layout, Modal, Menu, Dropdown, Badge, Avatar, Card, List, Button, Form, Input} from 'antd';
const { Header, Content, Footer, Sider } = Layout;
import {
    getRoleId,
} from "@/common/storage";
interface InitProps{
    
}
//函数组件
const RouterGuard:FC<InitProps> = (props:InitProps) =>{
    const { routerConfig, location } = props;
    let navigate = useNavigate();//因为使用了react-router-dom6以上的版本,所以路由跳转要使用useNavigate
    let [role_id,setRole_id] = useState<string|number>(getRoleId())
    //当天路由路径名
    let [targetRouterConfig,setTargetRouterConfig] = useState<boolean>(false)//判断当前路径是否匹配的上路由组,false为不存在,true为存在
    //useEffect(钩子)可以当做类组件的componentDidMount,componentDidUpdate 和 componentWillUnmount。当targetRouterConfig,role_id有变化,就需要执行一次useEffect类的函数
	useEffect(():any=>{
        renderContent(pathname,targetRouterData)
    },[targetRouterConfig,role_id])
	
    //渲染主要内容
    const renderContent = async (pathname:string,targetRouterData:RouterInterface)=>{
        let isLogin = getToken()?true:false;//是否登录
        //匹配上的路由数据
        for (let i in routerConfig) {

            //判断当前访问路径是否对应一级路由且没有二级路由
            if (routerConfig[i]['path'].toLowerCase() !== pathname.toLowerCase() && !routerConfig[i]['routes']) {
                targetRouterConfig=false;
            } else if (routerConfig[i]['path'].toLowerCase() !== pathname.toLowerCase() && routerConfig[i]['routes']) {
                //有二级路由进行匹配查找
                for (let q in routerConfig[i]['routes']) {
                    if (routerConfig[i]['routes'][q].path.toLowerCase() === pathname.toLowerCase()) {
                        targetRouterConfig=true;
                        targetRouterData = routerConfig[i]['routes'][q]
                        break;
                    }
                }
                if (targetRouterConfig) {
                    break;
                }
                //一级路由进行匹配查找
            } else if (routerConfig[i]['path'].toLowerCase() === pathname.toLowerCase()) {
                targetRouterConfig=true;
                targetRouterData = routerConfig[i]
                break;
            }
        }
        //判断是否登录
        if (isLogin) {
            let role_id = getRoleId();
            // 如果是登陆状态,想要跳转到登陆,重定向到主页
            if (pathname === "/login") {
                    return <Navigate to="/reservation/reservationList/ReservationList" />;
            } else {
                // 如果路由合法,就跳转到相应的路由
                //路由组里存在当前路径,并且当前路劲不需要登录,并且当前为非登录状态
                if (!targetRouterConfig) {
                    // 如果路由不合法,重定向到 404 页面
                    return  navigate("/404");
                }
            }
        }else if(!isLogin){
            // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
            if (targetRouterConfig) {
                showWarning("请先登录");
                return navigate("/login");
            } else {
                // 非登陆状态下,路由不合法时,重定向至 404
                return navigate("/404");
            }
        }
    }
    return (
        <Layout style={{ minHeight: '100vh' }}>           
                <Content style={{ margin: '0 16px' }}>
                    <Outlet />
                </Content>
        </Layout>
    );
}

export default RouterGuard;

3.根目录的App.tsx,动态生成路由

import React, {FC, lazy} from 'react';
import "@/App.less";
import { BrowserRouter, Routes, Route} from 'react-router-dom';
import {routes} from "@/router/index";
import RouterGuard from "@/router/routerGuard"
import {PageLoad} from "@/components/v1/common/loading/Loading";

const App:FC<any> = () =>{
    return (
        <div className="App">
            <BrowserRouter>
                <Routes>
                    <Route path="/" element={
                        <React.Suspense fallback={<PageLoad/>}>
                            <RouterGuard routerConfig={routes} />
                        </React.Suspense>
                    } >
                        {routes.map((v:any, i:any) => {
                            if (v.routes) {
                                return v.routes.map((vv:any, ii:any) => {
                                    return (
                                        <Route path={vv.path} element={
                                            <React.Suspense fallback={<PageLoad/>}>
                                                {vv.component}
                                            </React.Suspense>
                                        } />
                                    )
                                })
                            } else if(v.pageName !='error' && v.pageName !='login'){
                                return (
                                    <Route path={v.path} element={
                                        <React.Suspense fallback={<PageLoad/>}>
                                            {v.component}
                                        </React.Suspense>
                                    } />
                                )
                            }
                        })}
                    </Route>
                    {/*需要独立的页面*/}
                    {routes.map((v:any, i:any) => {
                        if(v.pageName =='error' || v.pageName =='login'){
                            if(v.path.toLowerCase() == "/404".toLowerCase()){
                                return(
                                    <Route path="*" element={
                                        <React.Suspense fallback={<PageLoad/>}>
                                            {v.component}
                                        </React.Suspense>
                                    } />
                                )
                            }else{
                                return (
                                    <Route path={v.path} element={
                                        <React.Suspense fallback={<PageLoad/>}>
                                            {v.component}
                                        </React.Suspense>
                                    } />
                                )
                            }
                        }
                    })}

                </Routes>
            </BrowserRouter>

        </div>

    );
}

export default App;

个人网站:沉默博客
如有错误,请多多指教。
如对你有帮助,给个赞吧。

举报

相关推荐

0 条评论