# 路由设计 > **文档版本**:v1.1 > **最后更新**:2025-01-18 --- ## 目录 1. [路由结构](#1-路由结构) 2. [路由配置](#2-路由配置) 3. [路由守卫](#3-路由守卫) 4. [路由辅助函数](#4-路由辅助函数) --- ## 1. 路由结构 ### 1.1 路由常量定义 ```typescript // src/constants/routes.ts export const ROUTES = { // 公开页面 HOME: "/", LOGIN: "/login", REGISTER: "/register", // 项目管理 PROJECTS: "/projects", PROJECT_DETAIL: "/projects/:projectId", // 编辑器 EDITOR: "/editor/:projectId", // 设置 SETTINGS: "/settings", PROFILE: "/settings/profile", PREFERENCES: "/settings/preferences", // 其他 NOT_FOUND: "/404", } as const; ``` ### 1.2 路由层级 ``` / # 首页 ├── /login # 登录页 ├── /register # 注册页 ├── /projects # 项目列表 │ └── /:projectId # 项目详情/编辑器 ├── /settings # 设置 │ ├── /profile # 个人资料 │ └── /preferences # 偏好设置 └── /404 # 404 页面 ``` --- ## 2. 路由配置 ### 2.1 Router 配置 ```typescript // src/app/Router.tsx import { createBrowserRouter, RouterProvider, Outlet } from 'react-router-dom'; import { lazy, Suspense } from 'react'; import { ROUTES } from '@constants/routes'; import { LoadingSpinner } from '@components/common'; import { ProtectedRoute } from './ProtectedRoute'; import { AppLayout } from '@components/layout/AppLayout'; // 懒加载页面 const HomePage = lazy(() => import('@/pages/HomePage')); const LoginPage = lazy(() => import('@/pages/LoginPage')); const ProjectsPage = lazy(() => import('@/pages/ProjectsPage')); const ProjectPage = lazy(() => import('@/pages/ProjectPage')); const NotFoundPage = lazy(() => import('@/pages/NotFoundPage')); // 页面加载 Wrapper function PageLoader({ children }: { children: React.ReactNode }) { return ( }> {children} ); } const router = createBrowserRouter([ { path: ROUTES.HOME, element: , }, { path: ROUTES.LOGIN, element: , }, { path: ROUTES.PROJECTS, element: ( ), }, { path: ROUTES.PROJECT_DETAIL, element: ( ), }, { path: '*', element: , }, ]); export function Router() { return ; } ``` ### 2.2 嵌套路由示例 ```typescript // 如果需要嵌套路由 const router = createBrowserRouter([ { path: '/', element: , children: [ { index: true, element: , }, { path: 'projects', element: , children: [ { index: true, element: , }, { path: ':projectId', element: , }, ], }, ], }, ]); ``` --- ## 3. 路由守卫 ### 3.1 认证守卫 ```typescript // src/app/ProtectedRoute.tsx import { Navigate, Outlet, useLocation } from 'react-router-dom'; import { useAppStore } from '@stores/appStore'; import { ROUTES } from '@constants/routes'; export function ProtectedRoute() { const user = useAppStore((state) => state.user); const location = useLocation(); if (!user) { // 保存当前位置,登录后跳转回来 return ; } return ; } ``` ### 3.2 权限守卫 ```typescript // src/app/RoleGuard.tsx import { Navigate } from 'react-router-dom'; import { useAppStore } from '@stores/appStore'; import { ROUTES } from '@constants/routes'; interface RoleGuardProps { children: React.ReactNode; allowedRoles: string[]; } export function RoleGuard({ children, allowedRoles }: RoleGuardProps) { const user = useAppStore((state) => state.user); if (!user || !allowedRoles.includes(user.role)) { return ; } return <>{children}; } // 使用示例 ``` ### 3.3 登录后重定向 ```typescript // src/pages/LoginPage.tsx import { useNavigate, useLocation } from 'react-router-dom'; import { useAppStore } from '@stores/appStore'; import { ROUTES } from '@constants/routes'; function LoginPage() { const navigate = useNavigate(); const location = useLocation(); const setUser = useAppStore((state) => state.setUser); const handleLogin = async (credentials: LoginCredentials) => { const user = await loginApi(credentials); setUser(user); // 登录后跳转到之前的页面,或默认跳转到项目列表 const from = location.state?.from?.pathname || ROUTES.PROJECTS; navigate(from, { replace: true }); }; return ; } ``` --- ## 4. 路由辅助函数 ### 4.1 路径生成函数 ```typescript // src/constants/routes.ts // 路由辅助函数 export const getProjectPath = (projectId: string) => `/projects/${projectId}`; export const getEditorPath = (projectId: string) => `/editor/${projectId}`; export const getSettingsPath = (tab?: string) => tab ? `/settings/${tab}` : '/settings'; // 使用示例 import { useNavigate } from 'react-router-dom'; import { getProjectPath } from '@constants/routes'; function ProjectCard({ project }: { project: Project }) { const navigate = useNavigate(); const handleClick = () => { navigate(getProjectPath(project.id)); }; return
{project.name}
; } ``` ### 4.2 路由参数 Hook ```typescript // src/hooks/useProjectRoute.ts import { useParams, useNavigate } from 'react-router-dom'; import { ROUTES } from '@constants/routes'; export function useProjectRoute() { const { projectId } = useParams<{ projectId: string }>(); const navigate = useNavigate(); const goToProject = (id: string) => { navigate(`/projects/${id}`); }; const goToProjects = () => { navigate(ROUTES.PROJECTS); }; return { projectId, goToProject, goToProjects, }; } // 使用示例 function ProjectPage() { const { projectId, goToProjects } = useProjectRoute(); if (!projectId) { return ; } return (
); } ``` ### 4.3 查询参数处理 ```typescript // src/hooks/useQueryParams.ts import { useSearchParams } from 'react-router-dom'; export function useQueryParams() { const [searchParams, setSearchParams] = useSearchParams(); const getParam = (key: string) => searchParams.get(key); const setParam = (key: string, value: string) => { const newParams = new URLSearchParams(searchParams); newParams.set(key, value); setSearchParams(newParams); }; const removeParam = (key: string) => { const newParams = new URLSearchParams(searchParams); newParams.delete(key); setSearchParams(newParams); }; return { getParam, setParam, removeParam, searchParams, }; } // 使用示例 function ProjectsPage() { const { getParam, setParam } = useQueryParams(); const filter = getParam('filter') || 'all'; const handleFilterChange = (newFilter: string) => { setParam('filter', newFilter); }; return (
); } ``` --- ## 5. 路由最佳实践 ### 5.1 懒加载 ```typescript // ✅ 推荐:使用懒加载 const ProjectPage = lazy(() => import("@/pages/ProjectPage")); // ❌ 避免:直接导入大型页面 import ProjectPage from "@/pages/ProjectPage"; ``` ### 5.2 错误边界 ```typescript // src/app/Router.tsx import { ErrorBoundary } from '@components/common/ErrorBoundary'; const router = createBrowserRouter([ { path: '/', element: , errorElement: , children: [ // ... 子路由 ], }, ]); ``` ### 5.3 路由预加载 ```typescript // 鼠标悬停时预加载 import { Link } from 'react-router-dom'; function ProjectCard({ project }: { project: Project }) { const handleMouseEnter = () => { // 预加载项目页面 import('@/pages/ProjectPage'); }; return ( {project.name} ); } ``` --- ## 相关文档 - [项目结构](./02-project-structure.md) - [状态管理](./04-state-management.md) - [开发规范](./13-dev-standards.md) --- **最后更新**:2025-01-18 | **版本**:v1.1