react-router-dom6路由守卫

react-router-dom6路由守卫,第1张

1:router.ts
import React, {Suspense , createElement} from "react";

import {getLocalStorage} from "../utils";
import {onRouteBeforeRule, RouteObjectRule} from "../react-router-dom6-guard";

const routes:RouteObjectRule[] = [
    {
        path : '*',
        redirect : '/home',
    },
    {
        path: '/home',
        page: () => import("../pages/Home/home"),
        meta: {
            auth: true
        },
        children: [
            {
                index: true, //设置默认
                path: '/home/*',
                meta: {
                    title: '个人主页',
                },
                page: () => import('../pages/Home/index/index')
            },
            {
                path: '/home/organization',
                meta: {
                    title: '组织机构管理',
                },
                page: () => import('../pages/Home/organization/index')
            },
        ],
    },
    {
        path: '/login',
        meta: {
            title: '登录',
        },
        page: () => import("../pages/login"),
    },
    {
        path: '/register',
        meta: {
            title: '注册',
        },
        page: () => import("../pages/register"),
    },
];

// //根据路径获取路由
const checkAuth = (routers: Array<RouteObjectRule>, path: string) => {
    for (const data of routers) {
        if (data.path == path) return data;
        if (data.children) {
            const res = checkAuth(data.children, path);
            if (res) return res;
        }
    }
    return null
};

// //根据路径,获取路由的详情
const checkRouterAuth = (path: string) => checkAuth(routes , path);

//全局路由守卫
const onRouteBefore :onRouteBeforeRule = (meta  , to) => {
    const {auth , title} = meta;
    if (title) {    // 动态修改页面title
        document.title = title || '统一中心管理';
    }
    // token权限验证
    if (auth && !getLocalStorage('access_token')) {
        return '/login';
    }
};
export default routes;
export {
    onRouteBefore,
    checkRouterAuth,
}


2:react-router-dom6-guard.tsx
import {useRoutes, RouteObject, Navigate, useLocation} from 'react-router-dom';
import React, {Suspense} from "react";

interface FunctionRule {
    (): void
}

//meta规则
interface MetaRule {
    auth ?: boolean, //是否需要登录
    title ?: string, //标题
    [name:string] : any //其他参数
}

//单个路由规则
interface RouteObjectRule extends RouteObject {
    children ?: RouteObjectRule[], //子路由
    page ?: FunctionRule, //route导入页面的对象
    path ?: string, //页面路径
    redirect ?: string, //重定向地址
    meta ?: MetaRule, //页面参数
}

interface onRouteBeforeRule {
    (meta : MetaRule , to : string) : void | string
}

interface GuardRule {
    routers : RouteObjectRule[],
    onRouterBefore ?: onRouteBeforeRule
}

let onRouterBefore : onRouteBeforeRule;

//路由导航,设置redirect重定向 和 auth权限
function Guard ({ element, meta}) {
    const { pathname } = useLocation();
    const nextPath = onRouterBefore ? onRouterBefore(meta ,pathname) : pathname;
    if (nextPath && nextPath !== pathname) {
        element = <Navigate to={nextPath} replace={true}/>;
    }
    return element;
}


// 路由懒加载
function lazyLoadRouters(page, meta){
    meta = meta || {};
    const LazyElement = React.lazy(page);
    const GetElement = ()=> {
        return (
            <Suspense fallback={<div className='global-loading'>页面加载中...</div>}>
                <LazyElement/>
            </Suspense>
        );
    };
    return <Guard element={<GetElement/>} meta={meta}/>;
}

function transRoutes(routes : RouteObjectRule[]) {
    const list = [];
    routes.forEach(route => {
        const obj = { ...route };
        if (obj.redirect) {
            obj.element = <Navigate to={obj.redirect} replace={true} />
        }
        if (obj.page) {
            obj.element = lazyLoadRouters(obj.page, obj.meta)
        }
        if (obj.children) {
            obj.children = transRoutes(obj.children)
        }
        ['redirect','page','meta'].forEach(name => delete obj[name]);
        list.push(obj)
    });
    return list
}

export type {
    RouteObjectRule,
    MetaRule,
    FunctionRule,
    onRouteBeforeRule,
}

const RouterGuard = (params : GuardRule) => {
    onRouterBefore = params.onRouterBefore;
    return useRoutes(transRoutes(params.routers))
};
export default RouterGuard;

3:app.ts
import React from 'react';
import routes , {onRouteBefore} from "./routers";
import {BrowserRouter} from "react-router-dom";
import {setLocalStorage , getLocalStorage} from "./utils";
import store , {actions} from './redux';
import RouterGuard from './react-router-dom6-guard';
export default function () {
    const UserInfo :any = getLocalStorage('userInfo');
    const access_token :any = getLocalStorage('access_token');
    if(UserInfo){
        store.dispatch(actions.setUserInfo(JSON.parse(UserInfo)));
        store.dispatch(actions.setToken(access_token));
    }
    window.addEventListener('beforeunload', (event) => {
        setLocalStorage('userInfo', JSON.stringify(store.getState().userInfo));
        setLocalStorage('access_token', store.getState().access_token);
    });
    return (
        <BrowserRouter>
            <RouterGuard routers={routes} onRouterBefore={onRouteBefore}/>
        </BrowserRouter>
    );
};
4:index.ts
import React from 'react';
import ReactDOM from 'react-dom';
import zhCN from 'antd/lib/locale/zh_CN';
import './assets/ali-fonts/iconfont.css';
import 'antd/dist/antd.less';
import './css/style.scss';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './redux';
import {Provider} from 'react-redux';
import {ConfigProvider} from 'antd';

ReactDOM.render(
    <Provider store={store}>
        <ConfigProvider locale={zhCN}>
            <App />
        </ConfigProvider>
    </Provider>,
    document.getElementById("root"),
);

reportWebVitals();

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1297679.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存