官网上对于Container
布局容器的描述以下图vue
Container
是一个容器组件,根据官网的描述它的子元素只能是
el-head
、
el-aside
、
el-main
、
el-footer
四者,而四者的父元素也只能是
Container
。咱们先来模仿
el-container
源码
模仿代码中均以el-test 替换el, 目的是为了边模仿边测试和el组件的效果对比node
<template>
<section class="el-test-container" :class="{'el-test-is-vertical': isVertical}">
<slot></slot>
</section>
</template>
<script>
export default {
name: 'ElTestContainer',
componentName: 'ElTestContainer',
props: {
direction: String
},
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 => {
let tag = vnode.componentOptions && vnode.componentOptions.tag
return tag === 'el-test-header' || tag === 'el-test-footer'
}) : false
}
},
}
</script>
复制代码
container
组件算是一个最基本的tempalte
形式的vue文件。浏览器
isVertical
是为了判断是否须要垂直布局,若是未设置,则根据子元素是否包含el--header
和el-footer
来决定。this.$slots
是组件的实例属性,由于组件是能够复用的VUE实例,所以和 new Vue()
同样,均还有如下属性bash
this.$slots
是否存在,若是存在,遍历
this.$slots.default
,即遍历
<slot></slot>
中的子元素,若是子元素中存在tag为
el-header
||
el-footer
则返回为true。此处
some
函数的使用是在若是有一个为
true
则返回
true
。
this.slots
this.$slots.default
的关系以下
console.log(this.$slots)
console.warn(this.$slots.default)
复制代码
this.$slots.defaullts
中的每个元素都是一个
VNode
,vue的节点,包含该元素的 全部信息,咱们所须要的
tag
属性,放在
componentOptions.tag
中。
VNode
的信息基本以下
<template>
<header class="el-test-header" :style="{height}">
<slot></slot>
</header>
</template>
<script>
export default {
name: 'ElTestHeader',
componentName: 'ElTestHeader',
props: {
height: {
type: String,
default: '60px'
}
}
}
</script>
复制代码
几个子组件的样式均长得差很少,不一样的在于样式文件中,el-head
和el-footer
均设置了flex-shrink = 0
表示子组件el-header
和el-footer
均不会被压缩。ide
container
组件基本简单,感受核心在于flex语法的应用,特别是flex-grow
flex-shrink
flex-basis
的应用。所以最后对于flex-grow, flex-shrink, flex-basis
作个总结函数
flex-grow
扩展比例布局
flex-shrink
收缩比例测试
flex-basis
伸缩基准值flex
当父元素设置了display:flex
属性的时候,子元素设置flex
便可生效。在flex
的三个属性当中,flex-basis
是做为基准值,是计算最后展示出来的子元素宽度的决定性因素,grow
shrink
是否起做用须要依赖于basis
。ui
假设咱们的样例代码
<div style="display:flex">
<div style="flex:1;border:1px solid red;height:30px;"></div>
<div style="flex:2;border:1px solid green;height:30px;"></div>
</div>
复制代码
此时flex
在浏览器中展示以下
此时两个子元素的basis
属性之和小于父元素的宽度,此时grow
会起做用。此时除了子元素自己宽度以外,剩余宽度将按照1:2的比例分配给两个子元素。 计算公式以下
(剩余空间m) = (父元素宽度width) - (子元素basic之和)
(当前子元素最终宽度final) = (剩余宽度m) * (当前子元素的grow值) / (因此子元素的grow值之和) + (当前子元素的basis)
复制代码
样例代码
<div style="display:flex">
<div style="flex:0 1 1000px;border:1px solid red;height:30px;"></div>
<div style="flex:0 4 1000px;border:1px solid green;height:30px;"></div>
</div>
复制代码
此时两个子元素的basis
属性之和大于父元素的宽度,此时shrink
会起做用。此时子元素basis
之和大于父元素宽度,basis
之和减去父元素宽度,获得的溢出宽度将按照1:4的比例压缩两个子元素。
计算公式以下
(溢出宽度m) = (子元素basis之和) - (父元素宽度width)
(当前子元素最终宽度final) = (当前子元素的basis) - (溢出宽度m) * (当前子元素的shrink值) / (因此子元素的shrink值之和)
复制代码
google看到了flex
存在三个关键字 none
initial
auto
以下所示