feat: 创建声明式路由配置系统'
This commit is contained in:
101
src/routes/index.js
Normal file
101
src/routes/index.js
Normal file
@@ -0,0 +1,101 @@
|
||||
// src/routes/index.js
|
||||
// 路由渲染器 - 根据配置自动生成 Routes
|
||||
|
||||
import React from 'react';
|
||||
import { Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { Box, useColorMode } from '@chakra-ui/react';
|
||||
|
||||
// 路由配置
|
||||
import { routeConfig, PROTECTION_MODES, getMainLayoutRoutes, getStandaloneRoutes } from './routeConfig';
|
||||
|
||||
// 布局组件 (非懒加载)
|
||||
import Auth from '../layouts/Auth';
|
||||
import HomeLayout from '../layouts/Home';
|
||||
import MainLayout from '../layouts/MainLayout';
|
||||
|
||||
// 保护路由组件
|
||||
import ProtectedRoute from '../components/ProtectedRoute';
|
||||
import ProtectedRouteRedirect from '../components/ProtectedRouteRedirect';
|
||||
|
||||
/**
|
||||
* 根据保护模式包装组件
|
||||
*/
|
||||
function wrapWithProtection(Component, protection) {
|
||||
if (protection === PROTECTION_MODES.MODAL) {
|
||||
return (
|
||||
<ProtectedRoute>
|
||||
<Component />
|
||||
</ProtectedRoute>
|
||||
);
|
||||
}
|
||||
|
||||
if (protection === PROTECTION_MODES.REDIRECT) {
|
||||
return (
|
||||
<ProtectedRouteRedirect>
|
||||
<Component />
|
||||
</ProtectedRouteRedirect>
|
||||
);
|
||||
}
|
||||
|
||||
// PUBLIC - 无保护
|
||||
return <Component />;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染单个路由
|
||||
*/
|
||||
function renderRoute(routeItem, index) {
|
||||
const { path, component, protection } = routeItem;
|
||||
|
||||
// 处理特殊组件(非懒加载)
|
||||
let Component;
|
||||
if (component === 'Auth') {
|
||||
Component = Auth;
|
||||
} else if (component === 'HomeLayout') {
|
||||
Component = HomeLayout;
|
||||
} else {
|
||||
Component = component;
|
||||
}
|
||||
|
||||
return (
|
||||
<Route
|
||||
key={`${path}-${index}`}
|
||||
path={path}
|
||||
element={wrapWithProtection(Component, protection)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AppRoutes - 应用路由组件
|
||||
* 替代 App.js 中的 Routes 部分
|
||||
*/
|
||||
export function AppRoutes() {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
// 分离路由
|
||||
const mainLayoutRoutes = getMainLayoutRoutes();
|
||||
const standaloneRoutes = getStandaloneRoutes();
|
||||
|
||||
return (
|
||||
<Box minH="100vh" bg={colorMode === 'dark' ? 'gray.800' : 'white'}>
|
||||
<Routes>
|
||||
{/* 带导航栏的主布局 - 所有需要导航栏的页面都在这里 */}
|
||||
<Route element={<MainLayout />}>
|
||||
{mainLayoutRoutes.map((route, index) => renderRoute(route, index))}
|
||||
</Route>
|
||||
|
||||
{/* 不使用布局的路由 */}
|
||||
{standaloneRoutes.map((route, index) => renderRoute(route, index))}
|
||||
|
||||
{/* 默认重定向到首页 */}
|
||||
<Route path="/" element={<Navigate to="/home" replace />} />
|
||||
|
||||
{/* 404 页面 */}
|
||||
<Route path="*" element={<Navigate to="/home" replace />} />
|
||||
</Routes>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppRoutes;
|
||||
44
src/routes/lazy-components.js
Normal file
44
src/routes/lazy-components.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// src/routes/lazy-components.js
|
||||
// 集中管理所有懒加载组件
|
||||
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* 懒加载组件配置
|
||||
* 使用 React.lazy() 实现路由懒加载,大幅减少初始 JS 包大小
|
||||
*/
|
||||
export const lazyComponents = {
|
||||
// 社区/内容模块
|
||||
Community: React.lazy(() => import('../views/Community')),
|
||||
ConceptCenter: React.lazy(() => import('../views/Concept')),
|
||||
StockOverview: React.lazy(() => import('../views/StockOverview')),
|
||||
LimitAnalyse: React.lazy(() => import('../views/LimitAnalyse')),
|
||||
|
||||
// 交易模块
|
||||
TradingSimulation: React.lazy(() => import('../views/TradingSimulation')),
|
||||
|
||||
// 事件模块
|
||||
EventDetail: React.lazy(() => import('../views/EventDetail')),
|
||||
|
||||
// 公司相关模块
|
||||
CompanyIndex: React.lazy(() => import('../views/Company')),
|
||||
ForecastReport: React.lazy(() => import('../views/Company/ForecastReport')),
|
||||
FinancialPanorama: React.lazy(() => import('../views/Company/FinancialPanorama')),
|
||||
MarketDataView: React.lazy(() => import('../views/Company/MarketDataView')),
|
||||
};
|
||||
|
||||
/**
|
||||
* 按需导出单个组件(可选)
|
||||
*/
|
||||
export const {
|
||||
Community,
|
||||
ConceptCenter,
|
||||
StockOverview,
|
||||
LimitAnalyse,
|
||||
TradingSimulation,
|
||||
EventDetail,
|
||||
CompanyIndex,
|
||||
ForecastReport,
|
||||
FinancialPanorama,
|
||||
MarketDataView,
|
||||
} = lazyComponents;
|
||||
190
src/routes/routeConfig.js
Normal file
190
src/routes/routeConfig.js
Normal file
@@ -0,0 +1,190 @@
|
||||
// src/routes/routeConfig.js
|
||||
// 声明式路由配置
|
||||
|
||||
import { lazyComponents } from './lazy-components';
|
||||
|
||||
/**
|
||||
* 路由保护模式
|
||||
* - 'modal': 使用 ProtectedRoute (弹窗模式登录)
|
||||
* - 'redirect': 使用 ProtectedRouteRedirect (跳转模式登录)
|
||||
* - 'public': 公开访问,无需登录
|
||||
*/
|
||||
export const PROTECTION_MODES = {
|
||||
MODAL: 'modal',
|
||||
REDIRECT: 'redirect',
|
||||
PUBLIC: 'public',
|
||||
};
|
||||
|
||||
/**
|
||||
* 路由配置
|
||||
* 每个路由对象包含:
|
||||
* - path: 路由路径
|
||||
* - component: 组件(从 lazyComponents 引用)
|
||||
* - protection: 保护模式 (modal/redirect/public)
|
||||
* - layout: 布局类型 (main/auth/none)
|
||||
* - meta: 路由元数据(可选,用于面包屑、标题等)
|
||||
*/
|
||||
export const routeConfig = [
|
||||
// ==================== 首页 ====================
|
||||
{
|
||||
path: 'home/*',
|
||||
component: 'HomeLayout', // 非懒加载,直接在 App.js 导入
|
||||
protection: PROTECTION_MODES.PUBLIC,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '首页',
|
||||
description: '价值前沿首页'
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 社区/内容模块 ====================
|
||||
{
|
||||
path: 'community',
|
||||
component: lazyComponents.Community,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '社区',
|
||||
description: '投资社区交流'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'concepts',
|
||||
component: lazyComponents.ConceptCenter,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '概念中心',
|
||||
description: '热门概念追踪'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'stocks',
|
||||
component: lazyComponents.StockOverview,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '股票概览',
|
||||
description: '全市场股票概览'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'limit-analyse',
|
||||
component: lazyComponents.LimitAnalyse,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '涨停分析',
|
||||
description: '涨停板数据分析'
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 交易模块 ====================
|
||||
{
|
||||
path: 'trading-simulation',
|
||||
component: lazyComponents.TradingSimulation,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '模拟交易',
|
||||
description: '模拟盘交易系统'
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 事件模块 ====================
|
||||
{
|
||||
path: 'event-detail/:eventId',
|
||||
component: lazyComponents.EventDetail,
|
||||
protection: PROTECTION_MODES.REDIRECT,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '事件详情',
|
||||
description: '事件详细信息'
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 公司相关模块 ====================
|
||||
{
|
||||
path: 'forecast-report',
|
||||
component: lazyComponents.ForecastReport,
|
||||
protection: PROTECTION_MODES.REDIRECT,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '财报预测',
|
||||
description: '上市公司财报预测'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'Financial',
|
||||
component: lazyComponents.FinancialPanorama,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '财务全景',
|
||||
description: '公司财务全景分析'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'company',
|
||||
component: lazyComponents.CompanyIndex,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '公司',
|
||||
description: '上市公司信息'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'company/:code',
|
||||
component: lazyComponents.CompanyIndex,
|
||||
protection: PROTECTION_MODES.REDIRECT,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '公司详情',
|
||||
description: '公司详细信息'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'market-data',
|
||||
component: lazyComponents.MarketDataView,
|
||||
protection: PROTECTION_MODES.MODAL,
|
||||
layout: 'main',
|
||||
meta: {
|
||||
title: '市场数据',
|
||||
description: '实时市场数据'
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 认证模块 ====================
|
||||
{
|
||||
path: 'auth/*',
|
||||
component: 'Auth', // 非懒加载,直接在 App.js 导入
|
||||
protection: PROTECTION_MODES.PUBLIC,
|
||||
layout: 'none',
|
||||
meta: {
|
||||
title: '登录/注册',
|
||||
description: '用户认证'
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取所有需要 MainLayout 的路由
|
||||
*/
|
||||
export function getMainLayoutRoutes() {
|
||||
return routeConfig.filter(route => route.layout === 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不需要布局的路由
|
||||
*/
|
||||
export function getStandaloneRoutes() {
|
||||
return routeConfig.filter(route => route.layout === 'none');
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路径查找路由配置
|
||||
*/
|
||||
export function findRouteByPath(path) {
|
||||
return routeConfig.find(route => route.path === path);
|
||||
}
|
||||
Reference in New Issue
Block a user