112 lines
4.3 KiB
Markdown
112 lines
4.3 KiB
Markdown
# 9.15 布局系统
|
||
|
||
:::tip 概述
|
||
前端布局采用经典的企业后台布局:左侧菜单 + 顶部导航 + 内容区域,支持多标签页导航。
|
||
:::
|
||
|
||
## 布局结构
|
||
|
||
```text
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 顶部导航栏 │
|
||
│ [Logo] [面包屑] [搜索] [通知] [头像] │
|
||
├──────────┬──────────────────────────────────────────────────┤
|
||
│ │ │
|
||
│ 侧边栏 │ 内容区域 │
|
||
│ 菜单 │ │
|
||
│ │ ┌──────────────────────────────────────────┐ │
|
||
│ ──────── │ │ 标签页导航 │ │
|
||
│ 系统管理 │ ├──────────────────────────────────────────┤ │
|
||
│ ├ 用户 │ │ │ │
|
||
│ ├ 角色 │ │ 页面内容 │ │
|
||
│ └ 菜单 │ │ │ │
|
||
│ │ │ │ │
|
||
│ 内容管理 │ │ │ │
|
||
│ ├ 文章 │ │ │ │
|
||
│ └ 分类 │ │ │ │
|
||
│ │ └──────────────────────────────────────────┘ │
|
||
└──────────┴──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 布局组件
|
||
|
||
```text
|
||
ui/src/layout/
|
||
├── index.vue # 布局入口
|
||
├── parentLayout.vue # 父级布局(路由嵌套用)
|
||
└── components/
|
||
├── Header/ # 顶部导航(AmendPwd 修改密码、Notifier 通知、ProjectSetting 项目设置)
|
||
├── Sider/ # 侧边栏菜单(动态菜单、折叠、主题)
|
||
├── Main/ # 内容区域(keep-alive 缓存)
|
||
├── TagsView/ # 标签页导航(多标签切换、关闭)
|
||
├── Logo/ # 品牌标识
|
||
└── Footer/ # 页脚
|
||
```
|
||
|
||
## 侧边栏菜单
|
||
|
||
菜单数据从后端 `GET /api/index/getMenus` 接口获取,由 `asyncRouteStore` 管理:
|
||
|
||
```typescript
|
||
// 菜单渲染逻辑
|
||
const menuList = asyncRouteStore.getMenus;
|
||
|
||
// 菜单数据结构
|
||
interface MenuItem {
|
||
id: number;
|
||
parentId: number;
|
||
name: string;
|
||
path: string;
|
||
component: string;
|
||
icon: string;
|
||
sort: number;
|
||
hide: boolean;
|
||
children?: MenuItem[];
|
||
}
|
||
```
|
||
|
||
:::tip 菜单数据即路由
|
||
侧边栏与动态路由消费**同一份** `getMenus` 数据(仅 `type=0` 可导航节点、`status=0`、`hide=0`、`is_delete=0`)——菜单管理里改 `hide` 即可隐藏入口而不删除路由。见 [9.5 路由与动态菜单](/zh/frontend/router.html)。
|
||
:::
|
||
|
||
## 标签页导航
|
||
|
||
标签页自动记录访问过的页面,支持:
|
||
|
||
- 点击切换
|
||
- 关闭当前/其他/全部
|
||
- 右键菜单操作
|
||
- keep-alive 缓存
|
||
|
||
```typescript
|
||
// 标签页 Store
|
||
const tabsViewStore = useTabsViewStore();
|
||
|
||
// 添加标签
|
||
tabsViewStore.addTab(route);
|
||
|
||
// 关闭标签
|
||
tabsViewStore.removeTab(route);
|
||
```
|
||
|
||
(keep-alive 组件列表由路由守卫 `afterEach` 统一维护,见 [9.5 路由与动态菜单](/zh/frontend/router.html)。)
|
||
|
||
## 响应式布局
|
||
|
||
布局支持桌面端和平板端:
|
||
|
||
- 桌面端:侧边栏默认展开
|
||
- 平板端:侧边栏默认折叠
|
||
- 侧边栏支持手动折叠/展开
|
||
|
||
```typescript
|
||
// 侧边栏折叠状态
|
||
const collapsed = ref(false);
|
||
|
||
// 响应式检测
|
||
const { width } = useWindowSize();
|
||
watchEffect(() => {
|
||
collapsed.value = width.value < 1024;
|
||
});
|
||
```
|