跳转到内容

Layout 布局 ​

用于构建带页头、侧栏、内容和页脚的页面骨架。

用法 ​

构建应用页面骨架

组件结构 ​

加粗的是必需部件。

data-scope="layout":root · header · sider-backdrop · sider · content · footer · sider-trigger

示例 ​

折叠侧栏 ​

保留侧栏节点并切换宽度

侧栏位置 ​

将侧栏放在行首或行尾

固定区域 ​

固定页头和侧栏

设计指引 ​

何时使用 ​

  • 构建管理后台、控制台或文档站。
  • 页面需要可折叠或响应式侧栏。

何时不用 ​

特性 ​

  • 页头、侧栏、内容和页脚均可选。
  • 侧栏折叠时保留节点和内部状态。
  • 支持自定义侧栏宽度、位置和断点。
  • 页头和侧栏可独立固定。
  • 应用设为 data-material="liquid" 时,固定的页头换成液态面:内容从它下面滚过时按下层换色调;不固定的页头保持原样。

组合 ​

  • 侧栏可放侧栏导航,页头可放菜单栏或工具栏。
  • 侧栏里放了侧栏导航时,侧栏内衬缺省为 0:导航自带内衬,两者宽度同取侧栏令牌,放进去正好铺满、不被裁。侧栏里其余内容也随之贴边,需要留白时写 --xh-layout-sider-padding。

最佳实践 ​

  • 固定页头或侧栏时,将滚动容器放在布局根外层。
  • 折叠宽度应容纳图标和内边距。

反模式 ​

  • 不要通过卸载侧栏实现折叠。
  • 不要绕过固定属性直接覆盖定位方式。

API 参考 ​

产物 ​

层值
自定义元素<xh-layout>
Vue 组件XhLayoutContent XhLayoutFooter XhLayoutHeader XhLayoutRoot XhLayoutSider XhLayoutSiderBackdrop XhLayoutSiderTrigger
组合式函数useLayout
状态机layoutMachine
皮肤@xihan-ui/styles/layout.css

Props ​

属性类型必填说明
siderCollapsedboolean受控折叠态:提供后由宿主决定。
defaultSiderCollapsedboolean非受控初始折叠态。
siderWidthstring展开时侧栏的宽度,任意 CSS 长度;未提供时使用皮肤中的档位。
siderCollapsedWidthstring折叠时侧栏的宽度,任意 CSS 长度;未提供时使用皮肤中的档位。
siderPlacementLayoutSiderPlacement侧栏挂在行首还是行尾,默认 start。
siderBreakpointLayoutBreakpoint侧栏的自适应断点:视口窄于该档时侧栏按折叠宽显示。 只切换宽度不改变折叠态:折叠态归 siderCollapsed 通道,两者互不干扰。 运行期更换档位会重新绑定媒体查询;需要所属 Window.matchMedia 与对应断点令牌。
siderPresentationLayoutSiderPresentation侧栏呈现形态,默认 inline(在骨架中占一列)。 sheet 是覆盖档:侧栏移出画外,展开时覆盖在内容之上并铺一层遮罩,内容因此占满整宽。 同时提供 siderBreakpoint 时它只在未达该档时成立:宽屏仍占一列,窄屏才覆盖, 且跨档时侧栏随之开合(进入覆盖档收起、回到占位档展开),经 siderCollapsed 通道。 覆盖档不锁定焦点、不把背后的内容标记为惰性:它是骨架中的一段,不是模态浮层。
headerFixedboolean头部吸顶:滚动时头部固定在滚动容器的上沿。只写标记,固定的实现归皮肤。
siderFixedboolean侧栏吸附:滚动时侧栏固定在滚动容器的上沿,头部也吸顶时让开头部的高度。只写标记,固定的实现归皮肤。
splitboolean在头部、侧栏、脚部与内容之间绘制分隔线。
onSiderCollapsedChange(details: LayoutSiderCollapsedChangeDetails) => void折叠态变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。
onSiderBreakpoint(details: LayoutSiderBreakpointDetails) => void跨过断点时发出一次,挂载或更换档位时也发出一次当前值。 窄屏需要把侧栏换成抽屉时接入该回调:组件自身只切换宽度。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
sider-collapsed-changeLayoutSiderCollapsedChangeDetails折叠态变化;detail 为 { collapsed: boolean }
sider-breakpointLayoutSiderBreakpointDetails跨过断点时发出,挂载时也发出一次当前值;detail 为 { matched: boolean }

状态 ​

以下名称仅用于内部状态机。

状态:expanded · collapsed

事件:SIDER.COLLAPSE · SIDER.EXPAND · SIDER.TOGGLE · CONTROLLED.COLLAPSE · CONTROLLED.EXPAND · PRESS.START · PRESS.END

判据:isSiderCollapsedControlled

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
siderCollapsedboolean侧栏当前是否折叠。
siderPresentationLayoutSiderPresentation已解析的侧栏呈现形态:提供断点时,覆盖档只在未达该档时成立。
setSiderCollapsed(next: boolean) => void
getRootProps() => T['element']
getHeaderProps() => T['element']
getSiderBackdropProps() => T['element']覆盖档铺在内容之上的遮罩:点击它收起侧栏。 占位档下它带 hidden,不占位也不接收指针。渲染时排在侧栏之前:两层同一个层号,覆盖顺序按文档序。
getSiderProps() => T['element']
getContentProps() => T['element']
getFooterProps() => T['element']
getSiderTriggerProps() => T['button']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Space / Enterfocus in sider-trigger折叠/展开 sider
Enter / Spaceheld in sider-trigger按住期间 sider-trigger 投影 data-pressed,与指针 :active 同一副按压面(text 档定尺按钮,按下缩放并换底);抬起或失焦撤下。把手没有禁用态
Escapesider 按覆盖档盖在内容之上收起 sider

ARIA ​

以下属性由 connect 生成。

部件属性值
sider-backdroparia-hidden'true'
sider-triggeraria-controlssider 部件的 id
sider-triggeraria-expanded'false' | 'true'

样式参考 ​

皮肤 ​

@xihan-ui/styles/layout.css 使用 [data-scope="layout"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-collapsed''(条件成立时才出现)
rootdata-header-fixed''(条件成立时才出现)
rootdata-sider-breakpointprops.siderBreakpoint
rootdata-sider-fixed''(条件成立时才出现)
rootdata-sider-placementprops.siderPlacement
rootdata-sider-presentationresolveSiderPresentation( prop('siderPresentation'), …
rootdata-split''(条件成立时才出现)
headerdata-fixed''(条件成立时才出现)
headerdata-xh-liquid''(条件成立时才出现)
sider-backdropdata-collapsed''(条件成立时才出现)
siderdata-collapsed''(条件成立时才出现)
siderdata-fixed''(条件成立时才出现)
siderdata-placementprops.siderPlacement
siderdata-presentationresolveSiderPresentation( prop('siderPresentation'), …
sider-triggerdata-collapsed''(条件成立时才出现)
sider-triggerdata-pressed''(条件成立时才出现)
sider-triggerdata-xh-action-control''
sider-triggerdata-xh-action-display'always'
sider-triggerdata-xh-action-profile'text'
sider-triggerdata-xh-action-size'sm'
sider-triggerdata-xh-action-variant'ghost'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-layout-bgrootbackgrounddefault--xh-bg-pagelayout 的 root 部件 background 覆盖槽。
--xh-layout-borderfooter
header
root
sider
border-block-end
border-block-start
border-inline-end
border-inline-start
fixed
material=liquid
placement=end
placement=start
presentation=sheet
split
where([data-material='liquid'])
xh-liquid
--xh-border-default
--xh-material-elevated-border
--xh-material-liquid-border
layout 的 footer、header、root、sider 部件 border-block-end、border-block-start、border-inline-end、border-inline-start 覆盖槽。
--xh-layout-content-paddingcontentpaddingdefault--xh-space-4layout 的 content 部件 padding 覆盖槽。
--xh-layout-fgrootcolordefault--xh-fg-defaultlayout 的 root 部件 color 覆盖槽。
--xh-layout-footer-bgfooterbackgrounddefault--xh-bg-surfacelayout 的 footer 部件 background 覆盖槽。
--xh-layout-footer-paddingfooterpaddingdefault--xh-space-3layout 的 footer 部件 padding 覆盖槽。
--xh-layout-header-bgheaderbackgrounddefault
fixed
material=liquid
where([data-material='liquid'])
xh-liquid
--xh-_liquid-bg
--xh-bg-surface
layout 的 header 部件 background 覆盖槽。
--xh-layout-header-gapheadergapdefault--xh-space-3layout 的 header 部件 gap 覆盖槽。
--xh-layout-header-hheader
root
sider
block-size
grid-template-rows
inset-block-start
max-block-size
default
fixed
header-fixed
sider-fixed
3.5remlayout 的 header、root、sider 部件 block-size、grid-template-rows、inset-block-start、max-block-size 覆盖槽。
--xh-layout-header-layerheaderz-indexfixed--xh-layer-stickylayout 的 header 部件 z-index 覆盖槽。
--xh-layout-header-pxheaderpadding-inlinedefault--xh-space-4layout 的 header 部件 padding-inline 覆盖槽。
--xh-layout-scrollport-hsidermax-block-sizefixed
presentation=sheet
100dvh
100vh
layout 的 sider 部件 max-block-size 覆盖槽。
--xh-layout-sider-backdrop-bgsider-backdropbackgrounddefault--xh-bg-overlaylayout 的 sider-backdrop 部件 background 覆盖槽。
--xh-layout-sider-backdrop-layersider-backdropz-indexdefault--xh-layer-drawerlayout 的 sider-backdrop 部件 z-index 覆盖槽。
--xh-layout-sider-bgsiderbackgrounddefault
presentation=sheet
--xh-bg-subtle
--xh-material-elevated-bg
layout 的 sider 部件 background 覆盖槽。
--xh-layout-sider-collapsed-wroot
sider
inline-sizecollapsed
sider-breakpoint
--xh-sider-collapsed-wlayout 的 root、sider 部件 inline-size 覆盖槽。
--xh-layout-sider-layersiderz-indexpresentation=sheet--xh-layer-drawerlayout 的 sider 部件 z-index 覆盖槽。
--xh-layout-sider-paddingsiderpadding
padding-block-end
padding-block-start
padding-inline
default
presentation=sheet
--xh-_layout-sider-paddinglayout 的 sider 部件 padding、padding-block-end、padding-block-start、padding-inline 覆盖槽。
--xh-layout-sider-shadowsiderbox-shadowpresentation=sheet--xh-material-elevated-shadowlayout 的 sider 部件 box-shadow 覆盖槽。
--xh-layout-sider-trigger-bgsider-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-restlayout 的 sider-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-layout-sider-trigger-bg-activesider-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedlayout 的 sider-trigger 部件 background-color 覆盖槽。
--xh-layout-sider-trigger-bg-hoversider-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverlayout 的 sider-trigger 部件 background-color 覆盖槽。
--xh-layout-sider-trigger-fgsider-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
layout 的 sider-trigger 部件 color 覆盖槽。
--xh-layout-sider-trigger-gapsider-triggergapdefault--xh-_action-profile-gaplayout 的 sider-trigger 部件 gap 覆盖槽。
--xh-layout-sider-trigger-pxsider-triggerpadding-inlinedefault--xh-_action-profile-padding-inlinelayout 的 sider-trigger 部件 padding-inline 覆盖槽。
--xh-layout-sider-trigger-radiussider-triggerborder-radiusdefault--xh-_action-profile-radiuslayout 的 sider-trigger 部件 border-radius 覆盖槽。
--xh-layout-sider-wroot
sider
inline-size@media (min-width: 1024px)
@media (min-width: 1280px)
@media (min-width: 640px)
@media (min-width: 768px)
default
presentation=sheet
sider-breakpoint=lg
sider-breakpoint=md
sider-breakpoint=sm
sider-breakpoint=xl
--xh-sider-wlayout 的 root、sider 部件 inline-size 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 指示与换位 · 出现 · 导航(见动效规范)。

inline-size · opacity · translate · visibility 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

响应式 ​

皮肤按视口分档:min-width: 1024px · min-width: 1280px · min-width: 640px · min-width: 768px。

  • siderBreakpoint 在指定断点以下折叠侧栏。
  • siderPresentation="sheet" 在窄屏以覆盖层显示侧栏。
  • 覆盖侧栏可通过遮罩或 Escape 收起。
  • 覆盖侧栏不是模态内容;模态导航使用抽屉。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。

Released under The MIT License