0x00简介
组件的布局网格布局(GridLayout)在上一篇文章中已经分析过,通过基本的24个页脚就可以快速、轻松地创建布局。
本文将介绍用于布局的容器组件,并利用Flexbox功能将其控制的区域设置为特定的布局,从而快速、轻松地构建页面的基本结构。 本文将深入剖析组件的源码,剖析其实现原理,耐心阅读,相信会对您有所帮助。组件文档
更多组件分析详情,请参见Element2源代码分析组件概述。
0x01 布局容器
布局容器提供5个组件,支持多层嵌套,快速构建页面的基本结构:
以上组件均采用flex布局,使用前请确保目标浏览器兼容。据悉的子元素只能是后四种,后四种的父元素也只能是
下面的代码可以通过多层嵌套实现常见的页面布局。 更常见的布局实现请参见官方文档。
Header
Aside
Main
Footer
0x02 代码实现容器布局容器
组件容器包装元素,包含一个没有后备内容的匿名套接字(默认)。 该组件定义了 Direction prop 属性elementui布局容器,用于子元素的排列方向。
// packagescontainersrcmain.vue
export default {
name: 'ElContainer',
componentName: 'ElContainer',
props: {
direction: String
},
computed: {
isVertical() {
// ...
}
}
};
如果没有定义direction属性的值,则组件通过标签判断子元素是否包含或时,所有子元素将垂直上下排列,否则将水平左右排列。 componentOptions类型定义
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;
}
}
标头底部容器
组件头封装了元素并包含一个槽。 组件定义了height的prop属性,设置底部容器的高度,默认值为60px。
// packagesheadersrcmain.vue
export default {
name: 'ElHeader',
componentName: 'ElHeader',
props: {
height: {
type: String,
default: '60px'
}
}
};
旁边的侧边栏容器
组件aside封装了元素并包含一个槽。 该组件定义了 width的 prop 属性,用于设置侧边栏的长度。 默认值为 300px。
// packagesasidesrcmain.vue
export default {
name: 'ElAside',
componentName: 'ElAside',
props: {
width: {
type: String,
default: '300px'
}
}
};
main 主要区域(内容)容器
组件main封装了元素,包括插槽。
// packagesmainsrcmain.vue
export default {
name: 'ElMain',
componentName: 'ElMain'
};
页脚顶部容器
组件页脚封装了元素并包含一个槽。 组件定义了height的prop属性,设置底部容器的高度elementui布局容器,默认值为60px。
// packagesfootersrcmain.vue
export default {
name: 'ElFooter',
componentName: 'ElFooter',
props: {
height: {
type: String,
default: '60px'
}
}
};
0x03 组件样式
组件样式源码使用scss混合指令b,when嵌套生成组件样式。
// packagestheme-chalksrccommonvar.scss
$--header-padding: 0 20px !default;
$--footer-padding: 0 20px !default;
$--main-padding: 20px !default;
// packagestheme-chalksrccontainer.scss
@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;
}
}
// packagestheme-chalksrcheader.scss
@include b(header) {
padding: $--header-padding;
box-sizing: border-box;
flex-shrink: 0;
}
// packagestheme-chalksrcfooter.scss
@include b(footer) {
padding: $--footer-padding;
box-sizing: border-box;
flex-shrink: 0;
}
// packagestheme-chalksrcmain.scss
@include b(main) {
// IE11 supports theelement partially https://caniuse.com/#search=main
display: block;
flex: 1;
flex-basis: auto;
overflow: auto;
box-sizing: border-box;
padding: $--main-padding;
}
// packagestheme-chalksrcaside.scss
@include b(aside) {
overflow: auto;
box-sizing: border-box;
flex-shrink: 0;
}
使用gulpfile.js编译scss文件并将其转换为CSS。 经过浏览器兼容和格式压缩后,最终生成的样式内容如下。
/* packagestheme-chalklibcontainer.css */
.el-container {
display: flex;
flex-direction: row;
flex: 1;
flex-basis: auto;
box-sizing: border-box;
min-width: 0;
}
.el-container.is-vertical {
flex-direction: column;
}
/* packagestheme-chalklibmain.css */
.el-main {
display: block;
flex: 1;
flex-basis: auto;
overflow: auto;
box-sizing: border-box;
padding: 20px;
}
/* packagestheme-chalklibaside.css */
.el-aside {
overflow: auto;
box-sizing: border-box;
flex-shrink: 0;
}
/* packagestheme-chalklibheader.css */
.el-header {
padding: 0 20px;
box-sizing: border-box;
flex-shrink: 0;
}
/* packagestheme-chalklibfooter.css */
.el-footer {
padding: 0 20px;
box-sizing: border-box;
flex-shrink: 0;
}
容器布局使用CSSFlexbox、flex-basis、flex-shrink、flex等属性实现句子模式请阅读Flex布局教程:句子模式阮一峰。
上面说了,的子元素只能是后四个,后四个的父元素也只能是。 因为只有容器组件被指定为flex布局,所以其他组件如果想让flex布局生效,只能将该组件作为容器的子组件。 事实上,容器可以是独立的。