当前位置: 首页 > news >正文

6.1Element UI布局容器

Element UI Container 与 Layout 布局详解

一、Container 布局容器

Container 布局容器用于整体页面布局,由以下组件构成,需遵循父子关系约束:

  • <el-container>:外层容器,子元素只能是 <el-header><el-aside><el-main><el-footer>
  • <el-header>:顶栏容器
  • <el-aside>:侧边栏容器
  • <el-main>:主要区域容器
  • <el-footer>:底栏容器

布局规则

  • 当子元素包含 <el-header> 或 <el-footer> 时,垂直排列
  • 否则水平排列(默认 flex 布局)
  • 需设置容器高度(通常为 100vh)以确保正常显示

示例代码

<el-container style="height: 100vh"><el-aside width="200px">侧边栏</el-aside><el-container><el-header>顶部栏</el-header><el-main>主要内容区</el-main><el-footer>底部栏</el-footer></el-container>
</el-container>

1. <el-container> 源码分析

<el-container> 是整个布局系统的根容器,它控制着子组件的排列方向

// 文件: packages/layout/src/container.vue
export default {name: 'ElContainer', // 组件名称// 接收一个可选的 'direction' propprops: {direction: {type: String,validator(val) {// 只接受 'horizontal' 或 'vertical'return ['horizontal', 'vertical'].indexOf(val) !== -1;}}},// 计算属性,用于动态生成 CSS 类名computed: {// 根据 'direction' prop 和子组件类型,确定排列方向// 如果没有指定 direction,则根据子组件中是否存在 <el-header> 或 <el-footer> 来推断// 如果有 <el-header> 或 <el-footer>,默认为垂直排列 (column)// 如果只有 <el-aside> 和 <el-main>,默认为水平排列 (row)// 这个推断逻辑通常在 mounted 或 render 函数中处理,这里简化为 computedclassObj() {if (this.direction === 'horizontal') {return 'is-horizontal';} else if (this.direction === 'vertical') {return 'is-vertical';} else {// 自动推断逻辑 (简化版)// 实际源码中会检查 $slots.default 中的子组件标签// const hasHeaderOrFooter = this.$slots.default.some(slot =>//   slot.componentOptions && ['el-header', 'el-footer'].includes(slot.componentOptions.tag)// );// return hasHeaderOrFooter ? 'is-vertical' : 'is-horizontal';return 'auto-direction'; // 代表自动推断}}},// 渲染函数render(h) {// 渲染一个 div,应用基础类名 'el-container' 和计算出的方向类名return h('section', { // 注意:实际源码可能用 'div',但为了语义化有时用 'section'class: ['el-container', this.classObj]}, this.$slots.default); // 插槽内容,即其子组件 (<el-header>, <el-aside> 等)}
};

关键点:

  • direction Prop: 允许显式指定布局方向 (horizontal 或 vertical)。
  • 自动推断: 如果没有设置 direction,组件会根据其子组件的内容自动推断方向。如果包含 <el-header> 或 <el-footer>,则推断为垂直 (column);如果只包含 <el-aside> 和 <el-main>,则推断为水平 (row)。这是实现多种布局模式(如 Header + Main vs Aside + Main)的关键。
  • 渲染: 最终渲染为一个 <section> 或 <div>,并带有 el-container 和方向类名(如 is-vertical)。

2. <el-header><el-aside><el-main><el-footer> 源码分析

这四个组件的源码结构极其相似,它们的主要区别在于默认的 CSS 样式可接受的 prop

// 通用模板 (以 <el-header> 为例,其他类似)
// 文件: packages/layout/src/header.vue (其他组件在对应文件)
export default {name: 'ElHeader', // 或 'ElAside', 'ElMain', 'ElFooter'props: {// 只有 <el-aside> 和 <el-header> 有 height/width prop// <el-main> 和 <el-footer> 通常没有,它们是自适应的height: { // <el-header> 和 <el-footer> 有 heighttype: String,default: '60px' // Element UI 默认高度},width: { // <el-aside> 有 widthtype: String,default: '300px' // Element UI 默认宽度 (注意:实际默认值可能在 CSS 或这里定义)}// <el-main> 和 <el-footer> 通常没有特定的 prop},render(h) {// 渲染一个 div,应用基础类名和组件特定的类名// 对于 <el-aside>,还会应用 :style 来设置 widthconst tag = this.$attrs.tag || 'header'; // 可以通过 tag prop 自定义标签const data = {class: ['el-header'], // 类名根据组件不同而变化: el-header, el-aside, el-main, el-footerstyle: {}};// 只有 <el-aside> 需要设置 width 样式// 只有 <el-header> 和 <el-footer> 需要设置 height 样式if (this.$options.name === 'ElAside' && this.width) {data.style.width = this.width;} else if (['ElHeader', 'ElFooter'].includes(this.$options.name) && this.height) {data.style.height = this.height;}return h(tag, data, this.$slots.default);}
};

关键点:

  • 简单渲染: 它们几乎不做任何逻辑处理,主要就是渲染一个带有特定类名的元素。
  • Props:
    • <el-aside>:接受 width (String),用于设置侧边栏宽度。
    • <el-header> / <el-footer>:接受 height (String),用于设置顶栏/底栏高度。
    • <el-main>不接受 height 或 width,它的尺寸由父容器和兄弟组件决定(通常是自适应填充剩余空间)。
  • tag Prop: 所有组件都支持 tag prop (通过 this.$attrs 透传),允许你自定义渲染的 HTML 标签(如将 <el-header> 渲染为 <header> 或 <div>)。

CSS 样式分析 (核心)

CSS 是实现布局行为的关键。以下是核心 CSS 规则的解读:

/* 基础容器样式 */
.el-container {display: flex;/* 默认是垂直方向,但会被 is-horizontal 覆盖 */flex-direction: column;/* 占据父容器的全部可用高度 *//* 注意:为了让 el-container 占满视口,通常需要设置 html, body, #app 的 height: 100%; */box-sizing: border-box;/* 其他基础样式 */
}/* 水平布局:当 direction="horizontal" 或自动推断为水平时添加 */
.el-container.is-horizontal,
.el-container.auto-direction /* 代表推断为水平 */ {flex-direction: row;
}/* 顶栏、底栏、侧边栏、主内容区的基础样式 */
.el-header,
.el-footer {/* 固定高度由 prop 或 CSS 默认值决定 *//* flex: 0 0 auto; 这是默认值,表示不伸缩,基于内容或设置的高度 */
}.el-aside {/* 固定宽度由 prop 决定 *//* flex: 0 0 auto; 不伸缩 */
}.el-main {/* 关键!主内容区会伸缩以填充剩余空间 */flex: 1;/* 占据除了固定高度/宽度组件之外的所有剩余空间 *//* min-width: 0; 可能需要设置,防止内容过长时 el-aside 被挤压 *//* 其他样式如 padding */
}/* 当容器是垂直排列时,.el-aside 和 .el-main 的组合 */
.el-container.is-vertical > .el-aside,
.el-container.auto-direction > .el-aside /* 推断为垂直时的 aside */ {/* 在垂直主轴上,aside 作为子项,需要设置其内部的 flex-direction 为 row *//* 这允许 aside 内部的 main 和其他元素水平排列 *//* 实际 CSS 可能更复杂,可能需要嵌套容器 *//* 但核心思想是,一个 vertical 的 container 包含一个 horizontal 的 container */
}/* 可能存在的嵌套规则 */
.el-container.is-vertical > .el-container {/* 内层容器在垂直主轴上 */flex-direction: row; /* 通常内层容器用于 Aside + Main,所以是 row */flex: 1; /* 内层容器也伸缩 */
}

CSS 核心要点:

  1. display: flex;: <el-container> 是一个 Flex 容器。
  2. flex-direction: 由 is-horizontal 或 is-vertical (或自动推断) 类名控制主轴方向。
  3. flex: 1; on <el-main>: 这是 <el-main> 能够自适应填充剩余空间的核心flex: 1 是 flex-grow: 1flex-shrink: 1flex-basis: 0% 的简写,意味着它会尽可能地伸展来占据可用空间。
  4. 固定尺寸: <el-header><el-footer> 的 height 和 <el-aside> 的 width 通过 style 属性(由 prop 设置)或 CSS 默认值来固定。
  5. 嵌套实现复杂布局: 像 Header + Aside + Main 这样的布局,实际上是 <el-container> (垂直) -> <el-header> + <el-container> (水平) -> <el-aside> + <el-main>。内层的 <el-container> 负责水平排列侧边栏和主内容。

Layout 栅格布局

基于 24 栏等宽划分,通过 <el-row> 和 <el-col> 组件实现灵活布局:

  1. el-row (行):

    • 相当于一个容器,用来包裹一组 el-col(列)。
    • 它本身是一个 display: flex 的容器。
    • 通过设置 el-row 的属性,可以控制其内部所有 el-col 的水平对齐 (justify)、垂直对齐 (align) 和列间距 (gutter)。
  2. el-col (列):

    • 代表布局中的一列。
    • 通过 span 属性来指定该列占据的份数。Element UI 的栅格系统默认将一行分为 24 份。
    • 例如:<el-col :span="12"> 表示该列占据一半(12/24)的宽度;<el-col :span="6"> 表示占据四分之一(6/24)的宽度。

核心属性

  1. 分栏设置:通过 span 属性定义占据列数(1-24)

    <el-row><el-col :span="8">占8列</el-col><el-col :span="16">占16列</el-col>
    </el-row>
    
  2. 间隔控制gutter 属性设置列间距(像素值)

    <el-row :gutter="20"><el-col :span="12"></el-col><el-col :span="12"></el-col>
    </el-row>
    
  3. 偏移设置offset 属性控制列偏移

    <el-col :span="6" :offset="6">向右偏移6列</el-col>
    
  4. 对齐方式:设置 type="flex" 启用 Flex 布局,通过 justify 控制水平对齐

    <el-row type="flex" justify="space-between"><el-col :span="6"></el-col><el-col :span="6"></el-col>
    </el-row>
    

注意事项

  • Container 组件需保持严格的父子组件关系
  • Layout 栅格支持响应式断点(如 :xs="8" :sm="12"
  • 复杂布局可组合使用两种方案(Container 作为整体框架,内部嵌套 Layout 栅格)

 

http://www.xdnf.cn/news/1361287.html

相关文章:

  • leetcode 162 寻找峰值
  • Polkadot - JAM
  • 13种常见机器学习算法总结
  • 青少年软件编程(python六级)等级考试试卷-客观题(2023年3月)
  • 学习制作记录(选项UI以及存档系统)8.24
  • 基于RISC-V架构的国产MCU在eVTOL领域的应用研究与挑战分析
  • 【Ollama】本地OCR
  • 波兰密码破译机bomba:二战密码战的隐形功臣
  • Shell 循环实战:while 与 until 的趣味编程之旅
  • 3.4 磁盘存储器 (答案见原书 P194)
  • 【重学MySQL】八十八、8.0版本核心新特性全解析
  • Unity的Cursor.lockState
  • DeepSeek对采用nginx实现透传以解决OpenShift 4.x 私有数据中心和公有云混合部署一套集群的解答
  • 【SBP】Unity 打包构建管线原理解析于对比
  • 联想win11笔记本音频失效,显示差号(x)
  • 半年网络安全转型学习计划表(每天3小时)
  • 从成本中心到价值创造者:网络安全运维的实施框架与价值流转
  • VMware centos磁盘容量扩容教程
  • Windows 系统下 Android SDK 配置教程
  • 使用 Frida 运行时检测 Android 应用的真实权限状态 (App Ops)
  • 强逆光干扰漏检率↓78%!陌讯多模态融合算法在光伏巡检的实战优化
  • Java全栈开发面试实战:从基础到高并发场景的深度解析
  • Python性能优化实战(二):让循环跑得比博尔特还快
  • 27.编程思想
  • 【golang长途旅行第30站】channel管道------解决线程竞争的好手
  • Teams Bot机器人实时语音识别的多引擎的处理
  • TCP--执行Linux命令(虚拟xshell)
  • 数据建模怎么做?一文讲清数据建模全流程
  • 一、基因组选择(GS)与基因组预测(GP)
  • 网络安全转型书籍清单