按需加载路由
This commit is contained in:
@@ -1,86 +1,110 @@
|
||||
import React from 'react';
|
||||
import { createBrowserRouter } from 'react-router-dom';
|
||||
import Layout from '../components/Layout';
|
||||
import ProtectedRoute from '../components/ProtectedRoute';
|
||||
import Login from '../pages/Login';
|
||||
import Home from '../pages/Home';
|
||||
import Devices from '../pages/Devices';
|
||||
import VideoControl from '../pages/Video';
|
||||
import Alerts from '../pages/Alerts';
|
||||
import Downloads from '../pages/Downloads';
|
||||
import Roles from '../pages/Roles';
|
||||
import Users from '../pages/Users';
|
||||
import SerialNumGenerate from '../pages/SerialNumGenerate';
|
||||
import MenuList from '../pages/MenuList';
|
||||
import Organization from '../pages/Organization';
|
||||
import StationManage from '../pages/StationManage';
|
||||
import React, { lazy, Suspense } from 'react';
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||
import type { RouteObject } from 'react-router-dom';
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
{
|
||||
path: '/login',
|
||||
element: <Login />,
|
||||
},
|
||||
{
|
||||
element: <ProtectedRoute />,
|
||||
children: [
|
||||
{
|
||||
path: '/',
|
||||
element: <Layout />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <Home />,
|
||||
},
|
||||
{
|
||||
path: 'devices',
|
||||
element: <Devices />,
|
||||
},
|
||||
{
|
||||
path: 'video',
|
||||
element: <VideoControl />,
|
||||
},
|
||||
{
|
||||
path: 'alerts',
|
||||
element: <Alerts />,
|
||||
},
|
||||
{
|
||||
path: 'downloads',
|
||||
element: <Downloads />,
|
||||
},
|
||||
{
|
||||
path: 'roles',
|
||||
element: <Roles />,
|
||||
},
|
||||
{
|
||||
path: 'users',
|
||||
element: <Users />,
|
||||
},
|
||||
{
|
||||
path: 'serialNumGenerate',
|
||||
element: <SerialNumGenerate />,
|
||||
},
|
||||
{
|
||||
path: 'menuList',
|
||||
element: <MenuList />,
|
||||
},
|
||||
{
|
||||
path: 'menuList',
|
||||
element: <MenuList />,
|
||||
},
|
||||
{
|
||||
path: 'organization',
|
||||
element: <Organization />,
|
||||
},
|
||||
{
|
||||
path: 'station',
|
||||
element: <StationManage />,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: <div className="p-10 text-center font-bold text-gray-400">模块开发中...</div>,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
// ============================================================
|
||||
// 路由懒加载 & 分层架构
|
||||
// 所有业务 Page 均通过 React.lazy 实现按需加载,减小首屏 JS 体积
|
||||
// ============================================================
|
||||
|
||||
// 布局组件
|
||||
const Layout = lazy(() => import('../components/Layout'));
|
||||
const ProtectedRoute = lazy(() => import('../components/ProtectedRoute'));
|
||||
const Login = lazy(() => import('../pages/Login'));
|
||||
|
||||
// 业务页面(按需加载)
|
||||
const Home = lazy(() => import('../pages/Home'));
|
||||
const Devices = lazy(() => import('../pages/Devices'));
|
||||
const Video = lazy(() => import('../pages/Video'));
|
||||
const Alerts = lazy(() => import('../pages/Alerts'));
|
||||
const Downloads = lazy(() => import('../pages/Downloads'));
|
||||
const Roles = lazy(() => import('../pages/Roles'));
|
||||
const Users = lazy(() => import('../pages/Users'));
|
||||
const MenuList = lazy(() => import('../pages/MenuList'));
|
||||
const Organization = lazy(() => import('../pages/Organization'));
|
||||
const StationManage = lazy(() => import('../pages/StationManage'));
|
||||
const SerialNumGenerate = lazy(() => import('../pages/SerialNumGenerate'));
|
||||
|
||||
// 公共加载骨架(路由切换时闪烁优化)
|
||||
function PageFallback() {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-full min-h-[200px]">
|
||||
<div className="w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 路由元信息表(权限 · 标题 · 图标)
|
||||
// ============================================================
|
||||
export const routeMeta: Record<string, {
|
||||
title: string;
|
||||
roles: string[];
|
||||
requiresAuth: boolean;
|
||||
}> = {
|
||||
'/': { title: '概览控制台', roles: ['admin', 'operator', 'viewer'], requiresAuth: true },
|
||||
'/devices': { title: '设备管理', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/video': { title: '在线视频', roles: ['admin', 'operator', 'viewer'], requiresAuth: true },
|
||||
'/alerts': { title: '警报中心', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/downloads': { title: '视频下载', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/serialNumGenerate': { title: '序列号生成', roles: ['admin'], requiresAuth: true },
|
||||
'/users': { title: '用户管理', roles: ['admin'], requiresAuth: true },
|
||||
'/roles': { title: '角色管理', roles: ['admin'], requiresAuth: true },
|
||||
'/menuList': { title: '菜单管理', roles: ['admin'], requiresAuth: true },
|
||||
'/organization': { title: '组织管理', roles: ['admin'], requiresAuth: true },
|
||||
'/station': { title: '场站管理', roles: ['admin'], requiresAuth: true },
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// 路由表(完整配置,支持权限过滤)
|
||||
// ============================================================
|
||||
const routes: RouteObject[] = [
|
||||
{
|
||||
path: '/login',
|
||||
element: (
|
||||
<Suspense fallback={<PageFallback />}>
|
||||
<Login />
|
||||
</Suspense>
|
||||
),
|
||||
},
|
||||
{
|
||||
element: (
|
||||
<Suspense fallback={<PageFallback />}>
|
||||
<ProtectedRoute />
|
||||
</Suspense>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
element: (
|
||||
<Suspense fallback={<PageFallback />}>
|
||||
<Layout />
|
||||
</Suspense>
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <Home /> },
|
||||
{ path: 'devices', element: <Devices /> },
|
||||
{ path: 'video', element: <Video /> },
|
||||
{ path: 'alerts', element: <Alerts /> },
|
||||
{ path: 'downloads', element: <Downloads /> },
|
||||
{ path: 'roles', element: <Roles /> },
|
||||
{ path: 'users', element: <Users /> },
|
||||
{ path: 'serialNumGenerate', element: <SerialNumGenerate /> },
|
||||
{ path: 'menuList', element: <MenuList /> },
|
||||
{ path: 'organization', element: <Organization /> },
|
||||
{ path: 'station', element: <StationManage /> },
|
||||
{
|
||||
path: '*',
|
||||
element: (
|
||||
<div className="flex flex-col items-center justify-center h-full gap-4 text-gray-400 select-none">
|
||||
<span className="text-6xl opacity-20">🚧</span>
|
||||
<p className="text-lg font-medium">模块开发中</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const router = createBrowserRouter(routes);
|
||||
|
||||
Reference in New Issue
Block a user