7.0elementplus布局容器详解
Element Plus 提供了一套基于 Flex 布局的 el-container
系统,用于快速搭建常见的页面整体布局结构。这套系统由几个核心组件构成:el-container
, el-header
, el-aside
, el-main
, el-footer
。它们共同协作,可以轻松构建出顶部导航、侧边栏、内容区、页脚等复杂布局。
布局容器
核心组件详解
<el-container>
- 作用: 布局的外层容器。它是其他布局组件(
el-header
,el-aside
,el-main
,el-footer
)的父容器。 - 特性:
- 默认使用
flex
布局,子元素会水平排列(flex-direction: row
)。 - 当它的直接子元素中没有
el-header
或el-footer
时,它会自动切换为垂直布局(flex-direction: column
)。这是实现侧边栏布局的关键。 - 可以嵌套使用,例如在一个
el-main
内部再使用一个el-container
来实现更复杂的布局。
- 默认使用
- 属性: 无特定属性,主要起容器和布局方向控制作用。
- 作用: 布局的外层容器。它是其他布局组件(
<el-header>
- 作用: 顶栏容器。
- 特性:
- 高度默认为 60px。
- 通常放置网站的 Logo、主导航菜单、用户信息、搜索框等。
- 属性:
height
: 自定义顶栏高度(如height="80px"
)。默认值是60px
。
<el-aside>
- 作用: 侧边栏容器。
- 特性:
- 宽度默认为 300px。
- 通常放置侧边导航菜单、分类列表、工具栏等。
- 属性:
width
: 自定义侧边栏宽度(如width="200px"
)。默认值是300px
。
<el-main>
- 作用: 主要区域容器。
- 特性:
- 占据剩余的全部可用空间。
- 这是页面内容的核心展示区域,如文章列表、表单、数据表格等。
- 属性: 无特定属性。
<el-footer>
- 作用: 底栏容器。
- 特性:
- 高度默认为 60px。
- 通常放置版权信息、备案号、底部链接等。
- 属性:
height
: 自定义底栏高度(如height="40px"
)。默认值是60px
。
布局模式与实现原理
Element Plus 的布局系统巧妙地利用了 el-container
的 flex-direction
切换规则来实现两种主要的布局模式:
水平布局模式 (默认)
- 触发条件:
el-container
的直接子元素中包含el-header
或el-footer
。 - 行为:
el-container
的flex-direction
为row
,子元素水平排列。 - 典型应用: 侧边栏布局 (
el-aside
+el-main
) 或 上下布局 (el-header
+el-main
+el-footer
)。 - 关键点: 在这种模式下,
el-aside
和el-main
会水平排列。
- 触发条件:
垂直布局模式
- 触发条件:
el-container
的直接子元素中不包含el-header
且不包含el-footer
。 - 行为:
el-container
的flex-direction
自动变为column
,子元素垂直排列。 - 典型应用: 顶部导航+内容布局 (
el-header
+el-main
) 或 顶部导航+侧边栏+内容+页脚 (el-header
+el-container
+el-footer
)。 - 关键点: 在这种模式下,
el-header
和el-main
会垂直排列。通常需要在el-header
和el-main
之外再包裹一层el-container
来容纳el-aside
和el-main
,并利用其垂直布局特性。
- 触发条件:
常用布局示例
侧边栏布局 (最常见)
<template><el-container style="height: 100vh;"> <!-- 设置容器高度为视口高度 --><!-- 侧边栏 --><el-aside width="200px" style="background-color: #d3dce6;"><el-menu :default-active="$route.path" router><el-menu-item index="/home"><el-icon><HomeFilled /></el-icon><span>首页</span></el-menu-item><el-menu-item index="/about"><el-icon><InfoFilled /></el-icon><span>关于</span></el-menu-item></el-menu></el-aside><!-- 主容器 (内部是垂直布局) --><el-container><!-- 顶栏 --><el-header style="background-color: #b3c0d1; color: #333; text-align: center; line-height: 60px;">后台管理系统</el-header><!-- 主要内容区 --><el-main style="background-color: #e9eef3; color: #333;"><router-view /> <!-- 动态内容通常放在这里 --></el-main><!-- 底栏 (可选) --><el-footer style="background-color: #b3c0d1; color: #333; text-align: center; line-height: 60px;">© 2025 公司名称</el-footer></el-container></el-container>
</template><script setup>
// 导入 Element Plus 图标
import { HomeFilled, InfoFilled } from '@element-plus/icons-vue'
</script><style>
/* 重置 body 和 html 的 margin,确保全屏 */
body, html {margin: 0;height: 100%;
}
</style>
- 解析:
- 外层
el-container
包含了el-aside
和一个内部的el-container
,因为有el-aside
(属于el-header
/el-footer
类别吗?不,el-aside
不是el-header
或el-footer
),所以外层el-container
保持row
水平布局,el-aside
和内部el-container
水平排列。 - 内部
el-container
的子元素是el-header
,el-main
,el-footer
。它包含el-header
和el-footer
,因此它的flex-direction
是row
?注意:这里有个常见的理解误区。实际上,内部el-container
的子元素是el-header
,el-main
,el-footer
,它包含el-header
和el-footer
,所以它应该保持row
?不! 关键在于,el-header
和el-footer
的存在不会阻止父容器el-container
切换到column
。正确的理解是:当el-container
的子元素中没有el-header
或el-footer
时,它才切换到column
。反过来说,只要子元素中有el-header
或el-footer
,它就保持row
。这显然不对,因为我们需要el-header
,el-main
,el-footer
垂直排列。 - 修正理解 (重要): Element Plus 的文档描述可能不够精确。实际行为是:
el-container
的默认flex-direction
是row
。只有当它的直接子元素中不包含el-header
且不包含el-footer
时,它才会应用一个类名(如.is-vertical
)将其flex-direction
改为column
。在示例1中,内部el-container
的子元素包含el-header
和el-footer
,所以它不会变成column
,它会保持row
!这会导致el-header
,el-main
,el-footer
水平排列,这不是我们想要的。 - 正确实现: 为了避免混淆,更可靠的做法是显式地为需要垂直排列的
el-container
添加direction="vertical"
属性
- 外层
Element Plus 的布局容器本身不直接提供响应式断点.使用 el-col
/el-row
(栅格系统) 来实现响应式效果
el-row
和 el-col
组件。这是 Element Plus 提供的响应式栅格系统(Grid System),是构建复杂、灵活、响应式页面布局的核心工具,尤其适用于需要精确控制元素宽度和排列的场景。
核心概念:栅格系统 (Grid System)
栅格系统是一种将页面水平划分为若干等宽列(Columns)的布局方法。通过将内容放置在不同数量的列上,并控制列之间的间距(Gutter),可以轻松实现对齐和响应式布局。
Element Plus 的栅格系统基于 24 列设计。这意味着每一行 (el-row
) 在水平方向上被划分为 24 个等宽的虚拟列。你可以通过设置 el-col
的 span
属性来指定它占据多少列(1-24),从而控制其宽度。
核心组件详解
<el-row>
- 作用: 行容器。用于包裹一组
el-col
组件,形成一行。el-col
必须作为el-row
的直接子元素。 - 特性:
- 使用
display: flex
实现布局,确保el-col
在行内正确排列。 - 负责控制行内列 (
el-col
) 之间的水平间距 (Gutter) 和垂直间距 (Gutter)。 - 可以设置对齐方式(水平和垂直)。
- 使用
- 属性:
gutter
: 核心属性。定义el-col
之间的间距(单位为 px)。它会将指定的值平均分配给每个el-col
的左右padding
。例如,gutter="20"
会使每个el-col
左右各有 10px 的padding
,从而在相邻列之间产生 20px 的视觉间距。默认值为0
。justify
: 定义el-col
在水平方向上的对齐方式。可选值:start
(默认): 左对齐。end
: 右对齐。center
: 居中对齐。space-around
: 间距在项目两侧平均分配。space-between
: 项目之间的间距相等,首尾项目紧贴边缘。
align
: 定义el-col
在垂直方向上的对齐方式。可选值:top
: 顶部对齐。middle
(默认): 居中对齐。bottom
: 底部对齐。
tag
: 自定义el-row
渲染的 HTML 标签。默认为div
。例如tag="section"
。
- 作用: 行容器。用于包裹一组
<el-col>
- 作用: 列容器。用于放置实际的内容。其宽度由
span
属性决定。 - 特性:
- 是
el-row
的直接子元素。 - 宽度通过
span
属性控制(占据 24 列中的多少列)。 - 支持响应式断点,可以根据屏幕宽度自动调整
span
值。 - 支持偏移 (offset),可以控制列从左侧开始空出多少列。
- 是
- 属性:
span
: 核心属性。指定el-col
占据的列数(1-24)。例如span="6"
表示占据 6/24 = 1/4 的行宽。span
的总和在同一行内通常应为 24,但也可以小于或大于(大于时会换行或溢出)。offset
: 列的左侧偏移列数。例如span="6" offset="6"
表示该列占据 6 列,并且从第 7 列(6列偏移)开始,前面空出 6 列。push
: 将列向右移动指定的列数(通过改变order
实现视觉顺序)。pull
: 将列向左移动指定的列数(通过改变order
实现视觉顺序)。xs
,sm
,md
,lg
,xl
: 响应式属性。这些属性允许你为不同屏幕尺寸指定不同的span
,offset
,push
,pull
值。它们接收一个数字(等同于span
)或一个对象{ span: number, offset: number, ... }
。xs
: 超小屏幕 (<768px)sm
: 小屏幕 (≥768px)md
: 中等屏幕 (≥992px)lg
: 大屏幕 (≥1200px)xl
: 超大屏幕 (≥1920px)
tag
: 自定义el-col
渲染的 HTML 标签。默认为div
。
- 作用: 列容器。用于放置实际的内容。其宽度由
工作原理与关键点
gutter
的实现:gutter
的值是通过给el-row
设置负的margin
,同时给el-col
设置正的padding
来实现的。例如:el-row
的margin-left
和margin-right
设置为-gutter/2
。el-col
的padding-left
和padding-right
设置为gutter/2
。- 这样,
el-col
内容之间的净间距就是gutter
,同时el-row
的左右边缘与容器边缘对齐。
span
与宽度:el-col
的宽度计算公式为(span / 24) * 100%
。例如,span=8
的宽度是33.33%
。换行: 当一行内
el-col
的span
总和超过 24 时,超出的el-col
会自动换行到下一行。响应式优先级: 响应式属性
xs
,sm
,md
,lg
,xl
是按从小到大的顺序定义的。当屏幕尺寸满足多个断点时,优先级更高的断点(更大的屏幕)的设置会覆盖优先级低的(更小的屏幕)。例如,如果同时设置了:sm="{span: 12}"
和:md="{span: 8}"
,那么在≥992px
(md) 的屏幕上,span
为 8;在≥768px
但<992px
(sm) 的屏幕上,span
为 12。
响应式布局
<template><el-row :gutter="20"><el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 8}" :lg="{span: 6}":xl="{span: 4}"><div class="grid-content bg-purple">响应式列</div></el-col><el-col :xs="{span: 24}" :sm="{span: 12, offset: 0}" :md="{span: 8, offset: 4}" :lg="{span: 6}":xl="{span: 4}"><div class="grid-content bg-purple-light">带偏移的响应式列</div></el-col></el-row>
</template>
- 解析:
- 第一列:
- 超小屏 (xs, <768px): 占满整行 (24列)。
- 小屏 (sm, ≥768px): 占半行 (12列)。
- 中屏 (md, ≥992px): 占 1/3 行 (8列)。
- 大屏 (lg, ≥1200px): 占 1/4 行 (6列)。
- 超大屏 (xl, ≥1920px): 占 1/6 行 (4列)。
- 第二列:
- 在中等屏幕 (md) 上,除了
span=8
,还设置了offset=4
,使其前面空出4列。
- 在中等屏幕 (md) 上,除了
- 效果: 随着屏幕变大,每列变得更窄,可以在一行内容纳更多列。
- 第一列: