AdminLayout
admin-layout搭出中后台外壳:侧栏导航、顶栏、多页签工作区和可滚动内容区
用法
基础骨架
侧栏品牌 + NavMenu + 顶栏 + 多页签 + 内容区;点菜单自动开页签(非受控)。
首页 / 仪表盘
3瑚
仪表盘
仪表盘
这是「仪表盘」页面内容。点击左侧菜单打开新页签,上方页签可切换 / 关闭,体验中后台 keep-alive 导航。
指标 1
1,234
指标 2
2,468
指标 3
3,702
指标 4
4,936
指标 5
6,170
指标 6
7,404
tsx
<AdminLayout
menuItems={menu}
logo={<span className="font-bold text-primary">瑚琏 Admin</span>}
defaultActiveKey="dashboard"
defaultSelectedKey="dashboard"
breadcrumb={<span className="text-sm text-muted-foreground">首页 / 仪表盘</span>}
headerExtra={<Avatar fallback="瑚" />}
>
<Dashboard />
</AdminLayout>默认收起侧栏
defaultCollapsed 让侧栏初始收起为图标轨,点顶栏汉堡可展开。
首页 / 仪表盘
瑚
仪表盘
仪表盘
这是「仪表盘」页面内容。点击左侧菜单打开新页签,上方页签可切换 / 关闭,体验中后台 keep-alive 导航。
指标 1
1,234
指标 2
2,468
指标 3
3,702
指标 4
4,936
指标 5
6,170
指标 6
7,404
tsx
<AdminLayout
menuItems={menu}
logo={<Logo />}
logoCollapsed={<span>瑚</span>}
defaultCollapsed
defaultActiveKey="dashboard"
>
<Dashboard />
</AdminLayout>隐藏多页签
showTabs={false} 关闭页签条,退化为单页内容(适合极简控制台)。
首页 / 仪表盘
瑚
仪表盘
这是「仪表盘」页面内容。点击左侧菜单打开新页签,上方页签可切换 / 关闭,体验中后台 keep-alive 导航。
指标 1
1,234
指标 2
2,468
指标 3
3,702
指标 4
4,936
指标 5
6,170
指标 6
7,404
tsx
<AdminLayout
menuItems={menu}
logo={<Logo />}
showTabs={false}
defaultSelectedKey="dashboard"
>
<Dashboard />
</AdminLayout>何时用
要快速搭一个完整中后台外壳——侧栏菜单 + 顶栏 + 多页签 keep-alive 导航开箱即用——用 AdminLayout,只需喂 menuItems 和 children。若想自己掌控每一块布局(不要内置页签逻辑、要更原子的拼装),下沉到 Layout。
导入
ts
import { AdminLayout } from "@hulianui/ui"Props
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| menuItems* | NavMenuNode[] | - | 侧边菜单数据(复用 NavMenu)。 |
| selectedKey | string | - | 受控菜单选中 key。 |
| defaultSelectedKey | string | - | 非受控初始选中 key。 |
| openKeys | string[] | - | 受控展开的子菜单 key。 |
| defaultOpenKeys | string[] | - | 非受控初始展开。 |
| collapsed | boolean | - | 受控侧栏折叠态。 |
| defaultCollapsed | boolean | - | 非受控初始折叠态。 |
| breakpoint | "sm"|"md"|"lg"|"xl"|"2xl"|number | - | 响应式断点(与 LayoutSider 同语义):视口 ≤ 该宽度自动收起侧栏、> 时展开。非受控直接改内部态;受控(传了 collapsed)时只触发 onCollapsedChange 由上层决定是否跟随。不设则不自动收起。 |
| showTabs | boolean | true | 是否显示多页签条。 |
| tabs | AdminTab[] | - | 受控页签列表;不传则由菜单点击自动维护(非受控)。 |
| activeKey | string | - | 受控当前激活页签 key。 |
| defaultActiveKey | string | - | 非受控初始激活页签(亦决定首屏自动打开的页签)。 |
| fitViewport | boolean | true | 是否自占满视口高度。整页应用骨架保持 true(固定 100dvh、内容区内部滚动);嵌入有固定高度的容器预览时置 false,改用 h-full 跟随父容器。 |
| className | string | - | 根容器类名。 |
| contentClassName | string | - | 内容区类名。 |
AdminTab:{ key: string; label: ReactNode; closable?: boolean },closable 缺省为「打开页签 >1 时可关,最后一个不可关」。
页签条本身是独立组件 RouteTabs —— 右键菜单、固定页签、拖拽调序、激活项滚入视口这些能力都在那边,本组件只是把它内嵌进骨架。自己搭骨架时直接用 RouteTabs。
Events
| 事件 | 类型 | 说明 |
|---|---|---|
| onMenuSelect | (key: string, item: NavMenuItem) => void | 点击菜单叶子项触发。 |
| onOpenChange | (openKeys: string[]) => void | 子菜单展开变化回调。 |
| onCollapsedChange | (collapsed: boolean) => void | 侧栏折叠变化回调。 |
| onTabChange | (key: string) => void | 切换页签回调。 |
| onTabClose | (key: string) => void | 关闭页签回调。 |
| onTabsAction | (action, tabKey, affectedKeys) => void | 页签右键菜单的批量动作(关闭其他/左侧/右侧/全部、刷新)。第三参是该动作实际影响到的 key 列表。⚠️ 受控(传了 `tabs`)时这是唯一出口:不接它,这些动作点了不会有任何变化 |
Slots
| 插槽 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 主内容(当前激活页内容,由上层按 activeKey 决定)。 |
| logo | ReactNode | 品牌区(展开态)。 |
| logoCollapsed | ReactNode | 品牌区(收起态,默认复用 logo)。 |
| breadcrumb | ReactNode | 顶栏面包屑区。 |
| headerExtra | ReactNode | 顶栏右侧扩展区(用户菜单 / 通知 / 主题切换等)。 |
禁忌 / 坑
- `collapsible` 可用时 `logoCollapsed` 应当必填。折叠后侧栏只有 64px,没给窄版标识就只能拿宽 logo 顶上,
overflow-hidden会把它裁掉半截——不报错,只是难看,所以开发期会打一次告警(#121)。传首字、单色图标、方形 mark 都行。 - 品牌区直接放 [Brand](/zh/components/brand):
logo={<Brand mark={…} name="…" />}、logoCollapsed={<Brand mark={…} />}。动图 / 视频 logo 也走 Brand 的mark(GIF、<picture>减弱动效回退、静音<video>都已给铺满规则),AdminLayout 的logo槽只负责摆位与对齐、不给媒体尺寸——裸传一张大图会按原尺寸被overflow-hidden裁掉。 - 顶栏与侧栏品牌区共用
--hl-layout-header-h,折叠态下品牌区自动切justify-center,与下方NavMenu mode="collapsed"的图标轨共用同一条中轴。改这块时别只切内容不切对齐。
- 受控页签下必须接 `onTabsAction`:组件不持有
tabs,右键菜单里的「关闭其他/左侧/右侧/全部」只能把「该关哪些」算给你,改不了。此前这里连回调都没有,受控消费方点了完全没反应。 - 「关闭全部」关的是全部可关页签(含当前页),不是「关闭其他」。此前二者行为相同、与菜单文案对不上。
- `fitViewport` 决定撑高方式:整页用默认
true(自钉 100dvh),别再外面套h-dvhwrapper;嵌入文档示例卡等固定高度容器时务必传false,否则整页滚动而非内容区滚动。详见 [[hulian-adminlayout-fitviewport]]。 - 页签受控/非受控二选一:不传
tabs时页签由菜单点击自动维护(非受控);一旦传tabs即受控,须自行配onTabChange/onTabClose维护数组与activeKey。 children只渲染「当前激活页」,keep-alive 的多页内容缓存需上层按activeKey自行管理,组件不替你缓存各页 DOM。- 移动端务必设 `breakpoint`(推荐
"md"):不设时窄屏侧栏保持展开,390px 视口下会挤占过半屏宽。为不破坏既有行为该项无默认值,需显式开启。
相关
Layout · ScrollArea · Viewport · Resizable · AspectRatio · FitScreen