Skip to content

Layout 布局

提供页头、侧边栏、内容区和页脚组合,适合搭建后台系统页面框架。

何时使用

  • 页面需要稳定组织 Header、Sidebar、Content、Footer 等区域。
  • 后台系统需要侧边导航和主内容区联动。
  • 侧边栏需要支持折叠、响应式收起或拖拽调整宽度。

基础用法

vue
<template>
  <x-layout class="demo-layout">
    <x-layout-header>Header</x-layout-header>
    <x-layout has-sidebar>
      <x-layout-sidebar :width="120">Sidebar</x-layout-sidebar>
      <x-layout-content>Content</x-layout-content>
    </x-layout>
    <x-layout-footer>Footer</x-layout-footer>
  </x-layout>
</template>

常见结构

Header
Content
Footer
Header
Left
Content
Right
Footer
vue
<template>
  <x-layout class="layout-doc-demo">
    <x-layout-header>Header</x-layout-header>
    <x-layout-content>Content</x-layout-content>
    <x-layout-footer>Footer</x-layout-footer>
  </x-layout>

  <x-layout class="layout-doc-demo">
    <x-layout-header>Header</x-layout-header>
    <x-layout has-sidebar>
      <x-layout-sidebar :width="128">Left</x-layout-sidebar>
      <x-layout-content>Content</x-layout-content>
      <x-layout-sidebar :width="128" reverse-arrow>Right</x-layout-sidebar>
    </x-layout>
    <x-layout-footer>Footer</x-layout-footer>
  </x-layout>
</template>

可折叠侧边栏

已展开
Content
vue
<template>
  <x-layout class="layout-doc-demo" has-sidebar>
    <x-layout-sidebar
      v-model:collapsed="collapsed"
      collapsible
      theme="dark"
      :width="180"
      :collapsed-width="56"
    >
      {{ collapsed ? '已收起' : '已展开' }}
    </x-layout-sidebar>
    <x-layout-content>Content</x-layout-content>
  </x-layout>
  <x-space>
    <x-button @click="collapsed = false">展开</x-button>
    <x-button @click="collapsed = true">收起</x-button>
  </x-space>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const collapsed = ref(false);
</script>

自定义触发器

Custom Trigger
收起
Content
vue
<template>
  <x-layout class="layout-doc-demo" has-sidebar>
    <x-layout-sidebar
      v-model:collapsed="collapsed"
      collapsible
      :width="180"
      :collapsed-width="64"
    >
      {{ collapsed ? 'Mini' : 'Custom Trigger' }}
      <template #trigger="{ collapsed: slotCollapsed }">
        {{ slotCollapsed ? '展开' : '收起' }}
      </template>
    </x-layout-sidebar>
    <x-layout-content>Content</x-layout-content>
  </x-layout>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const collapsed = ref(false);
</script>

响应式与事件

breakpoint="lg"
调整视口宽度查看收起状态
当前:展开
vue
<template>
  <x-layout class="layout-doc-demo" has-sidebar>
    <x-layout-sidebar
      v-model:collapsed="collapsed"
      collapsible
      breakpoint="lg"
      :width="190"
      :collapsed-width="72"
      @collapse="handleCollapse"
      @breakpoint="handleBreakpoint"
    >
      {{ collapsed ? 'lg' : 'breakpoint="lg"' }}
    </x-layout-sidebar>
    <x-layout-content>Content</x-layout-content>
  </x-layout>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const collapsed = ref(false);

const handleCollapse = (nextCollapsed: boolean, type: 'clickTrigger' | 'responsive') => {
  console.log(nextCollapsed, type);
};

const handleBreakpoint = (nextCollapsed: boolean) => {
  console.log(nextCollapsed);
};
</script>

可拖拽侧边栏

拖动右侧边缘
当前宽度:240px
vue
<template>
  <x-layout class="layout-doc-demo" has-sidebar>
    <x-layout-sidebar
      :width="sidebarWidth"
      :min-width="160"
      :max-width="520"
      :resize-directions="['right']"
      @moving="(size) => {
        sidebarWidth = size.width;
      }"
    >
      拖动右侧边缘
    </x-layout-sidebar>
    <x-layout-content>当前宽度:{{ sidebarWidth }}px</x-layout-content>
  </x-layout>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const sidebarWidth = ref(240);
</script>

与 Menu 组合

Menu 会跟随 Sidebar 折叠状态
vue
<template>
  <x-layout class="layout-doc-demo" has-sidebar>
    <x-layout-sidebar collapsible theme="dark" :width="210" :collapsed-width="64">
      <x-menu v-model:selected-keys="selectedKeys" theme="dark">
        <x-menu-item key="overview">概览</x-menu-item>
        <x-menu-sub-menu key="workspace" title="工作台">
          <x-menu-item key="components">组件</x-menu-item>
          <x-menu-item key="docs">文档</x-menu-item>
        </x-menu-sub-menu>
      </x-menu>
    </x-layout-sidebar>
    <x-layout-content>Content</x-layout-content>
  </x-layout>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const selectedKeys = ref(['overview']);
</script>

已知限制

  • collapsedWidth 可以设为 0,但当前不会生成侧边栏外部的零宽特殊触发器;需要重新展开时请提供外部按钮或自定义布局。
  • resizeDirections 会让 Sidebar 复用 ResizeBox 作为根组件,拖拽事件请参考 ResizeBox 文档。

按需导入

ts
import { Layout, LayoutHeader, LayoutContent, LayoutFooter, LayoutSidebar } from 'x-next';

Layout Props

参数说明类型默认值
hasSidebar是否包含侧边栏,SSR 场景可用于避免样式闪动booleanfalse

LayoutSidebar Props

参数说明类型默认值
theme侧边栏主题'dark' | 'light''light'
collapsed当前收起状态,可配合 v-model:collapsed 使用booleanundefined
defaultCollapsed默认收起状态,非受控用法booleanfalse
collapsible是否可收起booleanfalse
width展开宽度number | string200
collapsedWidth收起宽度number48
reverseArrow是否反转折叠箭头方向,右侧侧边栏可使用booleanfalse
breakpoint响应式断点'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'-
resizeDirections使用 ResizeBox 作为根组件后允许拖拽的方向Array<'left' | 'right' | 'top' | 'bottom'>-
hideTrigger是否隐藏折叠触发器booleanfalse

LayoutSidebar Events

事件名说明回调参数
update:collapsed收起状态变化时触发collapsed: boolean
collapse展开/收起时触发collapsed: boolean, type: 'clickTrigger' | 'responsive'
breakpoint响应式断点触发时触发collapsed: boolean

Slots

组件插槽名说明参数
Layoutdefault布局内容-
LayoutHeaderdefault页头内容-
LayoutContentdefault内容区-
LayoutFooterdefault页脚内容-
LayoutSidebardefault侧边栏内容-
LayoutSidebartrigger自定义折叠触发器{ collapsed }

Methods

当前组件没有通过 expose 暴露方法。