当前位置: 首页 > 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.dtcms.com/a/348689.html

相关文章:

  • 【Luogu】P2602 [ZJOI2010] 数字计数 (数位DP)
  • 基于大模型的对话式推荐系统技术架构设计-- 大数据平台层
  • 07 - spring security基于数据库的账号密码
  • window11无法连接Fortinet SSL VPN
  • Elasticsearch如何确保数据一致性?
  • 『深度编码』操作系统-进程之间的通信方法
  • 记录一下TVT投稿过程
  • 阿里云大模型应用实战:从技术落地到业务提效
  • Dify 从入门到精通(第 53/100 篇):Dify 的分布式架构(进阶篇)
  • 兑换汽水瓶
  • 关于并查集
  • 数字营销岗位需要具备的能力有哪
  • Java 内存模型(JMM)与并发可见性:深入理解多线程编程的基石
  • Flink session cluster与Flink per-job cluster区别
  • Zynq开发实践(Verilog、仿真、FPGA和芯片设计)
  • Linux-函数的使用-编写监控脚本
  • 栈的创建和基本操作
  • Arbess V1.1.4版本发布,支持Mysql数据库,Ubuntu系统,新增SSH及Hadess上传下载任务
  • week4-[字符数组]月份
  • TCP连接与UDP协议
  • 构建现代前端工程:Webpack/Vite/Rollup配置解析与最佳实践
  • C++20: std::span
  • 目标检测数据集 第005期-基于yolo标注格式的PCB组件检测数据集(含免费分享)
  • 【Ollama】本地OCR
  • 基于SpringBoot的校园信息共享系统【2026最新】
  • pod管理
  • scanner、arrylist、反转数组
  • FPGA 时序分析(五)
  • 十、redis 入门 之 redis事务
  • (Redis)主从哨兵模式与集群模式