feat: 添加路由树统一数据源,新增 antd/icons 依赖

This commit is contained in:
2026-05-15 11:41:45 +08:00
parent b6e2174b55
commit 5ab18fc612
5 changed files with 79 additions and 12 deletions

View File

@@ -25,8 +25,12 @@ src/
index.tsx # App entry point — mounts React root to #root
App.tsx # Root component — renders <RouterProvider>
App.css # Root component styles
router.tsx # Route config (createBrowserRouter)
router.tsx # createBrowserRouter,由 routes 树自动生成
env.d.ts # Rsbuild environment type declarations
routes/
types.ts # RouteItem 类型定义
index.tsx # 路由树数据(唯一数据源),导出 routes / RouteItem
utils.tsx # toRouteObjects():将路由树转为 React Router RouteObject[]
layouts/
RootLayout.tsx # Root layout with nav links and <Outlet />
pages/
@@ -44,9 +48,11 @@ tsconfig.json
Uses **React Router v7** (`react-router`) with `createBrowserRouter`.
- Route config lives in `src/router.tsx`
- `RootLayout` wraps all routes — add shared nav/header/footer there
- Add new pages under `src/pages/`, register them in `src/router.tsx`
- **唯一数据源**`src/routes/index.tsx` 维护 `routes: RouteItem[]` 路由树
- `RouteItem` 字段:`path` / `label` / `icon?` / `component?` / `hideInMenu?` / `redirect?` / `children?`
- `toRouteObjects(routes)` 将路由树转换为 React Router 所需的 `RouteObject[]`
- 菜单、面包屑等模块直接消费 `routes` 数组,无需重复维护路由信息
- 添加新页面:在 `src/pages/` 创建组件,在 `src/routes/index.tsx` 追加节点即可
## TypeScript Configuration

View File

@@ -1,18 +1,13 @@
import { createBrowserRouter } from 'react-router';
import RootLayout from './layouts/RootLayout';
import About from './pages/About';
import Home from './pages/Home';
import NotFound from './pages/NotFound';
import { routes } from './routes';
import { toRouteObjects } from './routes/utils';
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />,
children: [
{ index: true, element: <Home /> },
{ path: 'about', element: <About /> },
{ path: '*', element: <NotFound /> },
],
children: toRouteObjects(routes),
},
]);

25
src/routes/index.tsx Normal file
View File

@@ -0,0 +1,25 @@
import About from '../pages/About';
import Home from '../pages/Home';
import NotFound from '../pages/NotFound';
import type { RouteItem } from './types';
export const routes: RouteItem[] = [
{
path: '/',
label: '首页',
component: <Home />,
},
{
path: '/about',
label: '关于',
component: <About />,
},
{
path: '*',
label: '404',
component: <NotFound />,
hideInMenu: true,
},
];
export type { RouteItem };

18
src/routes/types.ts Normal file
View File

@@ -0,0 +1,18 @@
import type { ReactNode } from 'react';
export interface RouteItem {
/** 路由路径index 路由使用 '/' */
path: string;
/** 菜单/面包屑显示名称 */
label: string;
/** 菜单图标 */
icon?: ReactNode;
/** 页面组件,叶子节点必填(有 redirect 时忽略) */
component?: ReactNode;
/** 是否在菜单中隐藏,默认 false */
hideInMenu?: boolean;
/** 重定向目标路径,设置后忽略 component */
redirect?: string;
/** 子路由 */
children?: RouteItem[];
}

23
src/routes/utils.tsx Normal file
View File

@@ -0,0 +1,23 @@
import { Navigate } from 'react-router';
import type { RouteObject } from 'react-router';
import type { RouteItem } from './types';
export function toRouteObjects(items: RouteItem[]): RouteObject[] {
return items.map((item) => {
if (item.redirect) {
return { path: item.path, element: <Navigate to={item.redirect} replace /> };
}
const route: RouteObject = {
path: item.path === '/' ? undefined : item.path,
index: item.path === '/' ? true : undefined,
element: item.component,
};
if (item.children) {
route.children = toRouteObjects(item.children);
}
return route;
});
}