import React, { useMemo } from 'react'; import type { ReactNode } from 'react'; import { Routes, Route } from 'react-router-dom'; export interface Route { path: string; component: ReactNode; layout?: ReactNode; routes?: Route[]; childRoutes?: boolean; root?: boolean; } export function Router(props: { config: Route[] }) { const routeByLayout = useMemo(() => { const getRoute = (routes: Route[], basePath: string) => { // 存储本层路由配置 const layoutArr: ReactNode[] = []; const layoutRoute: Map = new Map(); // 存储最外层路由配置 const rootLayoutRoute: Map = new Map(); const isRoot = basePath === '' || basePath === '/'; // 遍历每条路由配置 routes.forEach((item, index) => { // 获取该条路由模版内容 let layoutComponent: ReactNode; if (item.layout) { layoutComponent = item.layout; } else { layoutComponent = ''; } // 获取该路由同一模版下路由列表 let routeConfig: ReactNode[]; if (item.root) { if (rootLayoutRoute.has(layoutComponent)) { routeConfig = rootLayoutRoute.get(layoutComponent) as ReactNode[]; } else { routeConfig = []; rootLayoutRoute.set(layoutComponent, routeConfig); } } else { if (layoutRoute.has(layoutComponent)) { routeConfig = layoutRoute.get(layoutComponent) as ReactNode[]; } else { layoutArr.push(layoutComponent); routeConfig = []; layoutRoute.set(layoutComponent, routeConfig); } } // 设置路由配置 let component: ReactNode; const childFlag = item.childRoutes ? `${item.path.endsWith('/') ? '' : '/'}*` : ''; const currentPath = `${basePath}${basePath.endsWith('/') ? '' : '/'}${ item.path }`; const routePath = item.root ? currentPath : item.path; if (item.path === '' || item.path === '/') { component = ( ); } else if (item.routes && item.routes.length) { // 处理子级冒泡上来的最外层路由 const { route, rootroute } = getRoute(item.routes, currentPath); rootroute.forEach((value, key) => { if (rootLayoutRoute.has(key)) { rootLayoutRoute.set(layoutComponent, [ ...(rootLayoutRoute.get(key) as ReactNode[]), ...value ]); } else { rootLayoutRoute.set(key, value); } }); component = ( {route} ); } else { component = ( ); } routeConfig.push(component); }); // 最外层合并路由 if (isRoot) { rootLayoutRoute.forEach((value, key) => { if (layoutRoute.has(key)) { layoutRoute.set(key, [ ...(layoutRoute.get(key) as ReactNode[]), ...value ]); } else { layoutArr.push(key); layoutRoute.set(key, value); } }); } // 生成路由节点 const route = layoutArr.map((layoutComponent, index) => { const routeComponents = layoutRoute.get(layoutComponent); if (layoutComponent === '') return ( {routeComponents} ); else { return ( {routeComponents} ); } }); return { route, rootroute: rootLayoutRoute }; }; const { route } = getRoute(props.config, ''); return route; }, [props.config]); return {routeByLayout}; }