官網上對於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
以下所示