Skip to content

布局系统

vue3-element-admin 提供了灵活的布局系统,支持多种布局模式和响应式设计。

布局模式

1. 经典布局(Left)

左侧菜单 + 顶部导航栏,最常用的后台管理布局。

┌────────────────────────────────────────┐
│             顶部导航栏                  │
├─────────┬──────────────────────────────┤
│         │                              │
│ 侧边栏  │          内容区域             │
│         │                              │
│         │                              │
└─────────┴──────────────────────────────┘

2. 顶部布局(Top)

顶部菜单 + 内容区域,适合菜单项较少的场景。

┌────────────────────────────────────────┐
│   Logo   菜单1   菜单2   菜单3          │
├────────────────────────────────────────┤
│                                        │
│              内容区域                   │
│                                        │
└────────────────────────────────────────┘

3. 混合布局(Mix)

顶部一级菜单 + 左侧二级菜单,适合菜单层级较深的场景。

┌────────────────────────────────────────┐
│ Logo  一级菜单1  一级菜单2  一级菜单3   │
├─────────┬──────────────────────────────┤
│二级菜单1│                              │
│二级菜单2│          内容区域             │
│二级菜单3│                              │
└─────────┴──────────────────────────────┘

布局配置

切换布局

在设置面板中可以切换不同的布局模式,配置存储在 settingsStore 中:

typescript
import { useSettingsStore } from '@/store/modules/settings'

const settingsStore = useSettingsStore()

// 切换布局
settingsStore.changeSetting('layout', 'left') // 经典布局
settingsStore.changeSetting('layout', 'top')  // 顶部布局
settingsStore.changeSetting('layout', 'mix')  // 混合布局

配置项

typescript
interface LayoutSettings {
  // 布局模式
  layout: 'left' | 'top' | 'mix'
  
  // 固定头部
  fixedHeader: boolean
  
  // 显示标签页
  tagsView: boolean
  
  // 侧边栏 Logo
  sidebarLogo: boolean
  
  // 侧边栏宽度
  sidebarWidth: number
  
  // 侧边栏折叠宽度
  sidebarCollapsedWidth: number
}

响应式设计

设备检测

布局系统会自动检测设备类型并调整布局:

typescript
import { useLayout } from '@/layouts/useLayout'

const { isMobile, isDesktop } = useLayout()

// 移动端自动收起侧边栏
watch(isMobile, (mobile) => {
  if (mobile) {
    appStore.closeSidebar()
  }
})

断点设置

设备断点说明
移动端< 768px侧边栏变为抽屉模式
平板768px - 992px侧边栏默认收起
桌面端> 992px完整布局

移动端适配

移动端下的布局变化:

  • 侧边栏变为抽屉模式,点击遮罩层关闭
  • 顶部导航栏简化
  • 标签页可左右滑动

布局组件

主布局

src/layouts/
├── index.vue           # 主布局入口
├── useLayout.ts        # 布局逻辑
└── components/
    ├── Sidebar/        # 侧边栏
    ├── Navbar/         # 顶部导航
    ├── TagsView/       # 标签页
    ├── AppMain/        # 内容区域
    └── Settings/       # 设置面板

侧边栏组件

侧边栏包含 Logo 和菜单:

vue
<template>
  <div class="sidebar-container">
    <Logo v-if="showLogo" :collapse="isCollapse" />
    <el-scrollbar>
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        :unique-opened="true"
        :collapse-transition="false"
      >
        <SidebarItem
          v-for="route in routes"
          :key="route.path"
          :item="route"
          :base-path="route.path"
        />
      </el-menu>
    </el-scrollbar>
  </div>
</template>

顶部导航

顶部导航包含折叠按钮、面包屑、功能按钮等:

vue
<template>
  <div class="navbar">
    <Hamburger />
    <Breadcrumb />
    
    <div class="right-menu">
      <Fullscreen />
      <SizeSelect />
      <LangSelect />
      <ThemeSwitch />
      <UserDropdown />
    </div>
  </div>
</template>

useLayout 组合函数

useLayout 提供了布局相关的状态和方法:

typescript
import { useLayout } from '@/layouts/useLayout'

const {
  // 状态
  isMobile,           // 是否移动端
  isDesktop,          // 是否桌面端
  sidebarOpened,      // 侧边栏是否展开
  
  // 方法
  toggleSidebar,      // 切换侧边栏
  closeSidebar,       // 关闭侧边栏
  openSidebar,        // 打开侧边栏
} = useLayout()

标签页

功能特性

  • 显示已打开的页面标签
  • 支持右键菜单(关闭、关闭其他、关闭全部)
  • 支持固定标签(affix)
  • 支持拖拽排序

配置

在路由 meta 中配置标签页行为:

typescript
{
  path: '/dashboard',
  meta: {
    title: '首页',
    affix: true,      // 固定标签,不可关闭
    keepAlive: true   // 页面缓存
  }
}

自定义布局

添加新布局

  1. src/layouts/components 下创建新布局组件
  2. src/layouts/index.vue 中注册
  3. 在设置中添加布局选项

修改侧边栏宽度

scss
// src/styles/variables.scss
$sidebar-width: 210px;
$sidebar-collapsed-width: 54px;

自定义顶部导航

src/layouts/components/Navbar 中添加自定义组件:

vue
<template>
  <div class="navbar">
    <!-- 自定义组件 -->
    <MyCustomComponent />
    
    <div class="right-menu">
      <!-- 功能按钮 -->
    </div>
  </div>
</template>

相关链接

基于 MIT 许可发布