项目layout布局
以下集成内容仅对布局思路进行描述解释,如需查看代码请前往 src/layout 目录查看实际代码,文档与代码会在git上持续补充
git仓库地址:https://gitee.com/xiaoli-account/react19_ts# 核心理念
对 React 单页面应用进行 layout 布局,与 React Router 进行配合
React 单页面应用的多层渲染机制
- 1、页面入口第一层:`index.html` - HTML 模板文件
- 2、页面入口第二层:`main.tsx` - React 应用挂载入口
- 3、页面入口第三层:`App.tsx` - 应用根组件,配置全局 Provider(ConfigProvider、BrowserRouter 等)
- 4、页面入口第四层:`AppRouter` - 路由配置组件,定义路由规则
- 5、页面入口第五层:`LayoutManager` - 布局管理器,根据配置动态渲染不同布局模式
- 6、页面入口第六层:`<Outlet />` - React Router 的路由出口,渲染匹配的页面组件
# 本项目 Layout 架构设计
布局模式
本项目支持三种布局模式,可通过 Zustand 状态管理动态切换:
1. **Lee Basic Layout(经典侧边栏模式)**
┌─────────────────────────────────────────┐│ Header 顶部栏 │├──────┬──────────────────────────────────┤│ │ Breadcrumb 面包屑 ││ Side ├──────────────────────────────────┤│ bar │ ││ 侧边 │ Content 内容区 ││ 菜单 │ (<Outlet />) ││ │ │└──────┴──────────────────────────────────┘
- 顶部:Logo + 用户信息 + 主题切换 + 语言切换
- 左侧:可折叠的侧边栏菜单
- 右侧:面包屑导航 + 页面内容区
效果图如下:
2. **Lee Sidebar Layout(纯侧边栏模式)**
┌──────┬──────────────────────────────────┐│ │ Breadcrumb 面包屑 ││ Side ├──────────────────────────────────┤│ bar │ ││ 侧边 │ Content 内容区 ││ 菜单 │ (<Outlet />) ││ │ │└──────┴──────────────────────────────────┘
- 无顶部栏,侧边栏包含 Logo 和菜单
- 适合内容优先的应用场景
效果图如下:
3. **Lee Top Menu Layout(顶部菜单模式)**
┌─────────────────────────────────────────┐│ Logo + Menu 菜单 + 用户信息 │├─────────────────────────────────────────┤│ Breadcrumb 面包屑 │├─────────────────────────────────────────┤│ ││ Content 内容区 ││ (<Outlet />) ││ │└─────────────────────────────────────────┘
- 顶部:Logo + 水平菜单 + 用户信息
- 适合菜单项较少的应用
效果图如下:
## 目录结构
src/layout/├── index.tsx # 布局管理器(LayoutManager)├── constants/ # 布局常量配置├── hooks/ # 布局相关 Hooks├── i18n/ # 布局国际化配置├── stores/ # 布局状态管理(Zustand)│ └── layoutStore.ts # 布局模式、侧边栏折叠状态等├── themes/ # 主题配置├── utils/ # 布局工具函数├── lee-basic-layout/ # 经典侧边栏布局│ ├── index.tsx # 布局主组件│ ├── header/ # 顶部组件│ ├── sidebar/ # 侧边栏组件│ ├── breadcrumb/ # 面包屑组件│ └── styles/ # 样式文件├── lee-sidebar-layout/ # 纯侧边栏布局└── lee-top-menu-layout/ # 顶部菜单布局
# 技术实现要点
1. React Router v7 路由配置
// src/router/index.tsx<Routes> <Routepath="/login"element={<Login />} /> {/* 布局路由 - 使用 LayoutManager 作为父路由 */} <Route path="/" element={<LayoutManager />}> <Routeindexelement={<Navigateto="/dashboard"replace />} /> <Routepath="dashboard"element={<Dashboard />} /> <Routepath="user-management"element={<UserManagement />} /> {/* 更多子路由... */} </Route> <Routepath="*"element={<Error404 />} /></Routes>
2. 布局管理器(LayoutManager)
// src/layout/index.tsxconst LayoutManager = () => { const { layoutMode } = useLayoutStore(); const renderLayout = () => { switch (layoutMode) { case 'lee-basic': return <LeeBasicLayout />; case 'lee-sidebar': return <LeeSidebarLayout />; case 'lee-top-menu': return <LeeTopMenuLayout />; default: return <LeeBasicLayout />; } }; return renderLayout();};
3. Zustand 状态管理
// src/layout/stores/layoutStore.tsexport const useLayoutStore = create<LayoutState>()( persist( (set, get) => ({ layoutMode: 'lee-basic', // 当前布局模式 sidebarCollapsed: false, // 侧边栏折叠状态 setLayoutMode: mode => set({ layoutMode: mode }), toggleSidebar: () => set({ sidebarCollapsed: !get().sidebarCollapsed }), }), { name: 'layout-storage' } ));
4. React Router 的 `<Outlet />` 组件
在每个布局组件中使用 `<Outlet />` 作为子路由的渲染出口:
// src/layout/lee-basic-layout/index.tsxconst LeeBasicLayout = () => { return ( <LayoutclassName="lee-basic-layout"> <Header /> <LayoutclassName="layout-main"> <Sidebar /> <LayoutclassName="layout-content"> <LayoutBreadcrumb /> <ContentclassName="content-wrapper"> <Outlet /> {/* 子路由在此渲染 */} </Content> </Layout> </Layout> </Layout> );};
5. Ant Design Layout 组件
使用 Ant Design 的 `Layout`、`Header`、`Sider`、`Content` 组件构建布局结构。
# 常见问题
1. 如何切换布局模式?
答:
使用 `useLayoutStore` 的 `setLayoutMode` 方法:
const { setLayoutMode } = useLayoutStore();setLayoutMode('lee-top-menu'); // 切换到顶部菜单模式
2. 如何控制侧边栏折叠?
答:
使用 `toggleSidebar` 或 `setSidebarCollapsed` 方法:
const { toggleSidebar, setSidebarCollapsed } = useLayoutStore();toggleSidebar(); // 切换折叠状态setSidebarCollapsed(true); // 设置为折叠
3. 如何在布局中添加新的全局功能?
答:
- 在对应布局目录下创建新组件(如 `header`、`sidebar`)
- 在布局主组件中引入并使用
- 如需跨布局共享,可放在 `src/layout/` 根目录下
4. 路由嵌套问题
问题:子路由无法正常渲染?
答:
- 确保父路由组件中包含 `<Outlet />` 组件
- 检查路由配置是否正确嵌套
- React Router v7 推荐使用扁平化路由,避免过深嵌套
5. 布局状态持久化
答:
使用 Zustand 的 `persist` 中间件,布局配置会自动保存到 `localStorage`,刷新页面后保持用户选择。
# 与 Vue 项目的主要差异
| 特性 | Vue 3 | React 19 || -------- | ----------------------- | -------------------- || 路由组件 | `<router-view>` | `<Outlet>` || 状态管理 | Pinia | Zustand || 动态组件 | `<component:is="xxx">` | 条件渲染 + Switch || 组件缓存 | `<keep-alive>` | 自定义实现或第三方库 || 过渡动画 | `<transition>` | CSS Modules 或动画库 |
# 结语
**代码是死的,人是活的。** 想要活学活用,首先需要理解:
1. **React Router 的嵌套路由机制**:父路由通过 `<Outlet />` 渲染子路由
2. **布局组件的职责分离**:每个布局模式独立封装,通过 LayoutManager 统一管理
3. **状态管理的作用**:使用 Zustand 管理布局配置,实现动态切换和持久化
项目千变万化,布局模式也随之不同。**理解思路** 后就能随心所欲,切勿照猫画虎,`切记!切记!`
以上仅做思路参考,而非像数学公式一样的标准答案。
代码可以被AI抄袭,思想不会,共勉!