Element UI 布局容器 Container 完全指南:el-container 系列组件源码解析与实战布局方案
2026/9/18 17:31:10 网站建设 项目流程

Element UI 布局容器 Container 完全指南:el-container 系列组件源码解析与实战布局方案

【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element

本篇指南围绕 Vue.js 2.0 组件库 Element UI(当前仓库eleme/element)中的布局容器组件展开,系统讲解<el-container><el-header><el-aside><el-main><el-footer>五个组件的职责划分、flex 布局原理、direction自动判定逻辑,以及七种经典页面骨架与一个完整后台管理实例的写法。读完本文,你将掌握用这几行组件快速搭建页头、侧边栏、主内容区、底栏任意组合的页面结构,并能结合源码理解其内部实现与属性默认值,在开发中做到即拿即用、心中有数。

组件总览:五个容器各司其职

Container 系列是 Element UI 中专门用于搭建页面基本结构的容器组件。官方文档(见 examples/docs/en-US/container.md)将其划分为五类:

组件语义职责
<el-container>外层容器包裹其余四个组件,决定子元素排列方向
<el-header>顶栏容器承载页面头部、工具栏、用户信息等
<el-aside>侧边栏容器承载侧边导航、次要信息栏
<el-main>主要区域容器承载页面主体内容
<el-footer>底栏容器承载版权信息、页脚工具等

在仓库中,五个组件分别位于独立包内,实现非常轻量,均只包含一个根元素与一个插槽(<slot>):

  • packages/container/src/main.vue:渲染<section class="el-container">
  • packages/header/src/main.vue:渲染<header class="el-header">
  • packages/aside/src/main.vue:渲染<aside class="el-aside">
  • packages/main/src/main.vue:渲染<main class="el-main">
  • packages/footer/src/main.vue:渲染<footer class="el-footer">

每个包入口(如 packages/container/index.js)都会注册install方法,通过Vue.component(Component.name, Component)完成全局注册,因此五个组件在引入 Element UI 后即可直接使用。

布局原理:flex 与 is-vertical 的自动判定

Container 系列采用 CSS flex 布局实现。从 packages/theme-chalk/src/container.scss 可以看到.el-container的完整样式:

@include b(container) { display: flex; flex-direction: row; flex: 1; flex-basis: auto; box-sizing: border-box; min-width: 0; @include when(vertical) { flex-direction: column; } }

核心逻辑是:.el-container默认为水平方向flex-direction: row),一旦加上is-vertical修饰类则切换为垂直方向flex-direction: column)。

is-vertical由 packages/container/src/main.vue 中的计算属性isVertical决定,其判定优先级如下:

  1. 显式传入direction="vertical"→ 强制垂直;
  2. 显式传入direction="horizontal"→ 强制水平;
  3. 未传direction时,遍历默认插槽中的 VNode,只要存在el-headerel-footer子组件,就自动判定为垂直排列,否则为水平排列。

对应源码片段:

computed: { isVertical() { if (this.direction === 'vertical') { return true; } else if (this.direction === 'horizontal') { return false; } return this.$slots && this.$slots.default ? this.$slots.default.some(vnode => { const tag = vnode.componentOptions && vnode.componentOptions.tag; return tag === 'el-header' || tag === 'el-footer'; }) : false; } }

这正是官方文档所述规则「子元素中有el-headerel-footer时为垂直,否则为水平」的源码依据。理解这一点后,你就能预判任意嵌套组合的排列方向,而不必记忆模板。

需要特别留意官方文档中的使用限制:

<el-container>的子元素只能是<el-header><el-aside><el-main><el-footer>这四者;反过来,后四者的父元素也只能是<el-container>

此外,因为整套方案依赖 flex,使用前请确认目标浏览器支持 flex 布局。

常见页面布局:七种骨架一键套用

下面这七种布局是官方文档给出的最常见页面骨架(原样继承自 examples/docs/en-US/container.md),可以直接复制到项目中按需使用。配套 CSS 为演示样式,用于区分各区域背景与文字居中。

<el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> <el-footer>Footer</el-footer> </el-container> <el-container> <el-aside width="200px">Aside</el-aside> <el-main>Main</el-main> </el-container> <el-container> <el-header>Header</el-header> <el-container> <el-aside width="200px">Aside</el-aside> <el-main>Main</el-main> </el-container> </el-container> <el-container> <el-header>Header</el-header> <el-container> <el-aside width="200px">Aside</el-aside> <el-container> <el-main>Main</el-main> <el-footer>Footer</el-footer> </el-container> </el-container> </el-container> <el-container> <el-aside width="200px">Aside</el-aside> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </el-container> <el-container> <el-aside width="200px">Aside</el-aside> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> <el-footer>Footer</el-footer> </el-container> </el-container> <style> .el-header, .el-footer { background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #D3DCE6; color: #333; text-align: center; line-height: 200px; } .el-main { background-color: #E9EEF3; color: #333; text-align: center; line-height: 160px; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } </style>

这七种布局覆盖了最常见的组合需求:

  1. 顶栏 + 内容区:最简洁的单列结构;
  2. 顶栏 + 内容区 + 底栏:完整的上下三段式;
  3. 侧边栏 + 内容区:经典左右两栏;
  4. 顶栏 +(侧边栏 + 内容区):嵌套容器实现「顶部通栏 + 下部左右分栏」;
  5. 顶栏 +(侧边栏 +(内容区 + 底栏)):三段式中仅主区域下方带底栏;
  6. 侧边栏 +(顶栏 + 内容区):侧栏通高、右侧上下分栏;
  7. 侧边栏 +(顶栏 + 内容区 + 底栏):最完整的后台管理骨架。

注意第 4~7 种布局都体现了「容器内嵌套容器」的用法,嵌套时内层<el-container>会自动根据其直接子元素(是否含el-header/el-footer)决定自己的排列方向,无需手动指定。

实战实例:完整的后台管理页布局

官方文档还给出了一个完整的「后台管理系统」示例:左侧为多级侧边导航(el-menu),右上为带下拉菜单的工具区(el-dropdown),中间主区域为数据表格(el-table)。该示例综合运用了 Container 系列与 Element UI 其他组件的组合能力,可直接改造为实际业务页面。

<el-container style="height: 500px; border: 1px solid #eee"> <el-aside width="200px" style="background-color: rgb(238, 241, 246)"> <el-menu :default-openeds="['1', '3']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-message"></i>Navigator One</template> <el-menu-item-group> <template slot="title">Group 1</template> <el-menu-item index="1-1">Option 1</el-menu-item> <el-menu-item index="1-2">Option 2</el-menu-item> </el-menu-item-group> <el-menu-item-group title="Group 2"> <el-menu-item index="1-3">Option 3</el-menu-item> </el-menu-item-group> <el-submenu index="1-4"> <template slot="title">Option4</template> <el-menu-item index="1-4-1">Option 4-1</el-menu-item> </el-submenu> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-menu"></i>Navigator Two</template> <el-menu-item-group> <template slot="title">Group 1</template> <el-menu-item index="2-1">Option 1</el-menu-item> <el-menu-item index="2-2">Option 2</el-menu-item> </el-menu-item-group> <el-menu-item-group title="Group 2"> <el-menu-item index="2-3">Option 3</el-menu-item> </el-menu-item-group> <el-submenu index="2-4"> <template slot="title">Option 4</template> <el-menu-item index="2-4-1">Option 4-1</el-menu-item> </el-submenu> </el-submenu> <el-submenu index="3"> <template slot="title"><i class="el-icon-setting"></i>Navigator Three</template> <el-menu-item-group> <template slot="title">Group 1</template> <el-menu-item index="3-1">Option 1</el-menu-item> <el-menu-item index="3-2">Option 2</el-menu-item> </el-menu-item-group> <el-menu-item-group title="Group 2"> <el-menu-item index="3-3">Option 3</el-menu-item> </el-menu-item-group> <el-submenu index="3-4"> <template slot="title">Option 4</template> <el-menu-item index="3-4-1">Option 4-1</el-menu-item> </el-submenu> </el-submenu> </el-menu> </el-aside> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right: 15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>View</el-dropdown-item> <el-dropdown-item>Add</el-dropdown-item> <el-dropdown-item>Delete</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <span>Tom</span> </el-header> <el-main> <el-table :data="tableData"> <el-table-column prop="date" label="Date" width="140"> </el-table-column> <el-table-column prop="name" label="Name" width="120"> </el-table-column> <el-table-column prop="address" label="Address"> </el-table-column> </el-table> </el-main> </el-container> </el-container> <style> .el-header { background-color: #B3C0D1; color: #333; line-height: 60px; } .el-aside { color: #333; } </style> <script> export default { data() { const item = { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }; return { tableData: Array(20).fill(item) } } }; </script>

该实例的结构要点:外层<el-container>只含<el-aside>与内层<el-container>(无el-header/el-footer直接子元素),因此外层水平排列;内层容器直接子元素含<el-header>,因此自动垂直排列。用户信息展示、下拉菜单、数据表格分别放在headermain区域中,aside通过width="200px"控制侧栏宽度。

属性 API 详解

四个组件各自暴露的属性非常精简,官方文档(examples/docs/en-US/container.md)给出的参数表如下:

Container Attributes

属性说明类型可选值默认值
direction子元素的排列方向stringhorizontal / vertical子元素中有el-headerel-footer时为 vertical,否则为 horizontal

direction对应源码 packages/container/src/main.vue 中的props.direction,其作用是强制覆盖自动判定逻辑:传入vertical强制垂直、horizontal强制水平,不传则由isVertical计算属性按插槽内容推断。这在需要「包含 header/footer 却仍想水平排列」或反之的特殊场景下非常有用。

Header Attributes

属性说明类型可选值默认值
height顶栏高度string60px

源码中height类型为String,默认'60px',通过内联样式:style="{ height }"绑定到<header>元素(见 packages/header/src/main.vue)。传入任何合法 CSS 长度值(如80px4rem)都会被原样应用。

Aside Attributes

属性说明类型可选值默认值
width侧边栏宽度string300px

源码中width类型为String,默认'300px',通过内联样式:style="{ width }"绑定到<aside>元素(见 packages/aside/src/main.vue)。注意文档示例中普遍使用width="200px",而默认值是300px,不传该属性时侧栏会按 300px 渲染。

Footer Attributes

属性说明类型可选值默认值
height底栏高度string60px

Headerheight完全对称,默认'60px',见 packages/footer/src/main.vue。

至于<el-main>,官方文档未列出任何属性,其源码 packages/main/src/main.vue 也确认它只声明了组件名、没有 props,纯粹作为内容承载区使用。

源码与测试验证

仓库单元测试 test/unit/specs/container.spec.js 对上述行为做了完整覆盖,可作为实现事实的印证:

  • vertical用例:渲染包含<el-header>的容器后,断言根元素包含is-verticalclass;
  • direction用例:先传direction="horizontal"断言不含is-vertical,再动态改为vertical并在$nextTick后断言 class 更新——验证了direction的响应式覆盖能力;
  • height/width用例:分别给<el-header height="100px"><el-aside width="200px"><el-footer height="100px">传参,断言最终el.style.height/el.style.width等于传入值——验证了属性通过内联样式生效;
  • 各组件create用例:验证组件可正常创建渲染。

从源码结构还可以推断:is-vertical依赖$slots.default中 VNode 的componentOptions.tag来识别子组件类型,因此判定发生在渲染阶段;这也意味着嵌套容器时,每一层都独立计算自己的方向,外层是否垂直不影响内层判定。

使用注意事项与最佳实践

  1. 方向判定规则要牢记direction显式值 > 插槽内容推断;推断只看直接子元素中是否出现el-header/el-footer。想要不受插槽影响地控制方向,务必显式传direction
  2. 嵌套层级按需拆分:复杂页面建议将「顶部通栏」「侧栏通高」「主区上下分栏」拆成独立的内层<el-container>,代码可读性更好,也避免一个容器内堆叠过多子元素导致方向推断出错。
  3. 宽度高度用 CSS 长度字符串width/height接受任何 CSS 长度值,如200px20%10rem;需响应式侧栏时可在aside外层再套一层控制宽度的容器。
  4. 配合其他布局组件使用:Container 系列负责整体骨架,内部单元格的栅格划分可交给el-row/el-col(见 packages/row/src/row.js 与 packages/col/src/col.js),两者组合即可覆盖从页面骨架到内容栅格的全链路布局需求。
  5. 浏览器兼容性:整体基于 flex,旧浏览器(如 IE9 及以下)不适用;现代浏览器均可放心使用。

综上,Element UI 的 Container 系列以极少的 API 和清晰的 flex 实现,提供了搭建任何常见页面骨架所需的全部能力。只要掌握了「外层容器 + 四种子容器」「direction 自动推断 + 显式覆盖」「嵌套容器独立判定」三个核心规律,就可以自由组合出任意形态的页面结构。

【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询