refactor: 页面状态由 URL 路由驱动 - 移除 usePageState/useNavigation/hooks/constants,改用嵌套路由 + useParams
This commit is contained in:
109
README.md
109
README.md
@@ -96,13 +96,11 @@ pnpm build # 验证打包(不运行pnpm dev,会挂起流程)
|
||||
src/
|
||||
├── components/ # 组件库
|
||||
│ ├── common/ # 通用组件 (Modal, Toast, EmptyState等)
|
||||
│ ├── layout/ # 布局组件 (AppHeader, AppLayout, UserDropdown等)
|
||||
│ ├── layout/ # 布局组件 (AppHeader, AppLayout, UserDropdown, ConsoleLayout, AdminLayout, DeveloperLayout等)
|
||||
│ ├── Layout.jsx # 主布局组件(sidebar + content)
|
||||
│ └── ListSelector.jsx # 列表选择器
|
||||
│
|
||||
├── contexts/ # 全局状态 (UserContext)
|
||||
├── hooks/ # 自定义Hook (usePageState, useNavigation)
|
||||
├── constants/ # 常量配置 (pages, storageKeys)
|
||||
├── services/ # 数据访问层 (api.js)
|
||||
├── data/ # 模拟数据
|
||||
│
|
||||
@@ -279,7 +277,9 @@ export default Example;
|
||||
|
||||
## 路由规范
|
||||
|
||||
### 顶层路由
|
||||
### 嵌套路由结构
|
||||
|
||||
所有页面通过正式路由导航,使用 HashRouter + 嵌套路由。
|
||||
|
||||
```jsx
|
||||
// App.jsx
|
||||
@@ -288,9 +288,29 @@ export default Example;
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route element={<AppLayout />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/console" element={<ConsolePage />} />
|
||||
<Route path="/admin" element={<AdminPage />} />
|
||||
<Route path="/developer" element={<DeveloperPage />} />
|
||||
|
||||
<Route path="/console" element={<ConsoleLayout />}>
|
||||
<Route index element={<Navigate to="chat/welcome" replace />} />
|
||||
<Route path="chat" element={<ChatPage />} />
|
||||
<Route path="chat/:scene" element={<ChatPage />} />
|
||||
<Route path="skills" element={<SkillsPage />} />
|
||||
<Route path="skills/:skillId" element={<SkillDetailPage />} />
|
||||
{/* ...更多子路由 */}
|
||||
</Route>
|
||||
|
||||
<Route path="/admin" element={<AdminLayout />}>
|
||||
<Route index element={<Navigate to="overview" replace />} />
|
||||
<Route path="overview" element={<OverviewPage />} />
|
||||
<Route path="departments" element={<DepartmentsPage />} />
|
||||
<Route path="departments/add" element={<AddDepartmentPage />} />
|
||||
<Route path="departments/:id/edit" element={<AddDepartmentPage />} />
|
||||
{/* ...更多子路由 */}
|
||||
</Route>
|
||||
|
||||
<Route path="/developer" element={<DeveloperLayout />}>
|
||||
<Route index element={<Navigate to="overview" replace />} />
|
||||
{/* ...子路由 */}
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</HashRouter>
|
||||
@@ -299,41 +319,33 @@ export default Example;
|
||||
**说明**:
|
||||
- `AppLayout` 包裹所有需要统一 Header 的页面
|
||||
- 登录页独立,不使用 `AppLayout`
|
||||
- 每个模块(Console/Admin/Developer)使用独立的 Layout 组件包裹 `<Outlet />`
|
||||
- 模块根路径自动重定向到默认子页面
|
||||
- 新增/编辑表单通过 URL 参数区分:`/admin/departments/add` vs `/admin/departments/:id/edit`
|
||||
|
||||
### 子页面路由
|
||||
|
||||
每个主页面内部管理子页面:
|
||||
### 子页面参数获取
|
||||
|
||||
```jsx
|
||||
// ConsolePage.jsx示例
|
||||
const [currentPage, setCurrentPage] = useState('chat');
|
||||
|
||||
const renderPage = () => {
|
||||
switch (currentPage) {
|
||||
case 'chat': return <ChatPage />;
|
||||
case 'skills': return <SkillsPage />;
|
||||
// ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 页面配置
|
||||
|
||||
```javascript
|
||||
// constants/pages.js
|
||||
export const CONSOLE_PAGES = {
|
||||
chat: { title: '智能助手', icon: 'FiMessageSquare' },
|
||||
skills: { title: '技能市场', icon: 'FaPuzzlePiece' },
|
||||
// 使用 useParams 获取 URL 参数
|
||||
function SkillDetailPage() {
|
||||
const { skillId } = useParams();
|
||||
const skill = api.skills.getById(Number(skillId));
|
||||
// ...
|
||||
};
|
||||
}
|
||||
|
||||
// 使用 useNavigate 进行导航
|
||||
function SkillsPage() {
|
||||
const navigate = useNavigate();
|
||||
return <button onClick={() => navigate('/console/skills/1')}>查看</button>;
|
||||
}
|
||||
```
|
||||
|
||||
### 新增页面流程
|
||||
|
||||
1. 在 `constants/pages.js` 添加页面配置
|
||||
2. 在父页面组件导入新页面
|
||||
3. 在 `renderPage()` 添加case分支
|
||||
4. 添加导航项(如需要)
|
||||
1. 在 `App.jsx` 添加路由定义
|
||||
2. 创建页面组件(使用 `useParams` / `useNavigate`)
|
||||
3. 在对应 Layout 的 sidebar 添加导航项
|
||||
4. 确保页面返回按钮使用固定路径导航
|
||||
|
||||
---
|
||||
|
||||
@@ -351,28 +363,17 @@ function Component() {
|
||||
}
|
||||
```
|
||||
|
||||
### 页面状态持久化
|
||||
### 页面状态由 URL 驱动
|
||||
|
||||
| 模块 | localStorage键 | 默认值 |
|
||||
|------|---------------|--------|
|
||||
| 工作台 | `console_currentPage` | `'chat'` |
|
||||
| 管理台 | `admin_currentPage` | `'overview'` |
|
||||
| 开发台 | `developer_currentPage` | `'overview'` |
|
||||
所有页面状态(当前页面、场景名、实体 ID)通过 URL 参数驱动,不依赖 localStorage。
|
||||
|
||||
### 自定义Hook
|
||||
|
||||
```javascript
|
||||
// usePageState - 页面状态持久化
|
||||
const { currentPage, setCurrentPage } = usePageState({
|
||||
storageKey: CONSOLE_KEYS.CURRENT_PAGE,
|
||||
defaultPage: 'chat',
|
||||
pageTitles: CONSOLE_PAGES,
|
||||
});
|
||||
|
||||
// useNavigation - 导航逻辑
|
||||
const { navigateToPage, extraData } = useNavigation(setCurrentPage);
|
||||
navigateToPage('skillDetail', { skillId: '1' });
|
||||
```
|
||||
| 状态类型 | 驱动方式 | 示例 |
|
||||
|---------|---------|------|
|
||||
| 当前页面 | URL 路径 | `/console/skills` |
|
||||
| 实体 ID | URL 参数 | `/console/skills/:skillId` |
|
||||
| 场景名 | URL 参数 | `/console/chat/:scene` |
|
||||
| 新增/编辑模式 | URL 参数有无 | `/admin/users/add` vs `/admin/users/:id/edit` |
|
||||
| 编辑数据 | `api.getById(Number(id))` | 通过 ID 重新获取 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user