Introduction to the
The so-called layout container is the overall structure of the page, generally speaking, it is
container
The Container components
As the name implies, it is a container component that hosts child components. What characteristics should container components have? Blocky, highly adaptive, etc. Element adds a rule: If the child element contains
or
, all child elements will be vertically arranged up and down, otherwise horizontally arranged left and right. This is not surprising
<template>
<section class="el-container" :class="{ 'is-vertical': isVertical }">
<slot></slot>
</section>
</template>
<script>
export default {
name: 'ElContainer'// Custom attributes are used for other components:'ElContainer',
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 => {
const tag = vnode.componentOptions && vnode.componentOptions.tag;
return tag === 'el-header' || tag === 'el-footer';
})
: false; }}}; </script>Copy the code
This is a typical single-file vUE component, but the style part has been separated out. If you look at the Template part, you will see that it is just a
in
@import "mixins/mixins"; @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; }}Copy the code
isVertical() {...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;
}
Copy the code
This.$slots&& this.$slots.default returns false if it does not exist, then the child element is empty. This.$slots is an instance attribute of a component. A component is an instance of a reusable Vue, just like new Vue(), so it has the following attributes
this.$slots.default
some
<el-header>
<el-footer>
some
every
This.$slots.default is an array. Each element is a VNode. Vnodes are virtual nodes in the virtual DOM. > generates a virtual node, roughly as shown in the following figure
componentOptions
const vnode = new VNode(
`vue-component-${Ctor.cid}${name ? `-${name}` : ' '}`,
data, undefined, undefined, undefined, context,
{ Ctor, propsData, listeners, tag, children },
asyncFactory
)
Copy the code
ComponentOptions are {Ctor, propsData, listeners, tag, children} componentOptions are componentlisteners Printing out the VNode proves the above statement
So here’s a heuristic for how to determine the type of child elements. In summary, the function that evaluates attributes can determine its own Flex layout direction from child elements
Footer component
Since the rest of the components are very similar, I’ll analyze a Footer as follows
<template>
<footer class="el-footer" :style="{ height }">
<slot></slot>
</footer>
</template>
<script>
export default {
name: 'ElFooter'// custom attributes to make it easier for other components to get the componentName componentName:'ElFooter',
props: {
height: {
type: String,
default: '60px'}}}; </script>Copy the code
This still encapsulates the native
@import "mixins/mixins";
@import "common/var";
@include b(footer) {
padding: $--footer-padding;
box-sizing: border-box;
flex-shrink: 0;
}
Copy the code
Note the flex-shrink:0 code, which means that when the parent container becomes too small, the footer will not shrink but keep its original width. In other words, the footer will never shrink, even if it exceeds the container. Flex-shrink defaults to 1, which is equal scale shrinkage of all elements, for a layout like the one shown below
flex-shrink
flex:1
flex:grow:1,flex:shrink:1,flex-basis:auto
flex:grow
conclusion
All in all, the layout is essentially a wrapper around native containers, and if the browser does not support Flex, the layout will not work