I. Component introduction

[website links] (component | Element (gitee. IO))

The EL-Container component is a container component used for layout. It is used to build the basic structure of the page.

It is usually used with el-header, el-aside, el-main, and el-footer.

Second, source code analysis

2.1 Container Component code

container.vue

<template>// The outer layer uses the native section tag<section class="el-container" :class="{'is-vertical': isVertical}">// Provide a default slot<slot></slot>
  </section>
</template>
<script lang="ts">
import { defineComponent, computed, VNode, Component } from 'vue'

export default defineComponent({
  name: 'ElContainer'.props: {
    direction: {
      type: String.default: ' ',}},setup(props, { slots }) {
    // Determine whether the vertical layout is used. If the vertical layout is used, set the flex-direction to column
    const isVertical = computed(() = > {
      // Explicitly pass in the layout direction
      if (props.direction === 'vertical') {
        return true
      } else if (props.direction === 'horizontal') {
        return false
      }
      if (slots && slots.default) {
        const vNodes: VNode[] = slots.default()
        return vNodes.some(vNode= > {
          const tag = (vNode.type as Component).name
          // If the child element contains' 
       
         'or' 
        
          ', all child elements will be vertically up and down, otherwise horizontally left and right.
        
       
          return tag === 'ElHeader' || tag === 'ElFooter'})}else {
        return false}})return {
      isVertical,
    }
  },
})
</script>
Copy the code
@import 'mixins/mixins';
/ / BEM
@include b(container) {
  / / flex layout
  display: flex; 
  flex-direction: row;
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  min-width: 0;
  
  / / vertical
  @include when(vertical) {
    flex-direction: column; }}Copy the code

2.2 Header component code

header.vue

<template>// Native header tags<header class="el-header"/ / setcssLocal variable, override global variable, dynamic settingheaderhighly:style="{ '--el-header-height': height }">// Default slot<slot></slot>
  </header>
</template>
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'ElHeader'.props: {
    height: {
      type: String.default: null,}}})</script>
Copy the code

header.scss

@import 'mixins/mixins';
@import 'common/var';

:root {
  --el-header-padding: 0 20px;
  // Global CSS variable that specifies the default height of the header
  --el-header-height: 60px;
}

@include b(header) {
  padding: var(--el-header-padding);
  box-sizing: border-box;
  flex-shrink: 0;
  // Adjust the height using CSS variables
  height: var(--el-header-height);
}
Copy the code

Note: The implementation of the footer/aside code is exactly the same as the header and will not be detailed separately

2.3 Main component code

main.vue

<template>// The native main tag<main class="el-main">// Default slot<slot></slot>
  </main>
</template>
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'ElMain',})</script>
Copy the code

main.scss

@import 'mixins/mixins';
@import 'common/var';

:root {
  --el-main-padding: 20px;
}

@include b(main) {
  // IE11 supports the <main> element partially https://caniuse.com/#search=main
  display: block;
  // Fill up the remaining space
  flex: 1;
  flex-basis: auto;
  overflow: auto;
  box-sizing: border-box;
  padding: var(--el-main-padding);
}

Copy the code

2.4 conclusion:

  1. Container/header/footer/value/main internal use corresponding HTML 5 native label, have semantic;
  2. Container uses flex layout.
  3. Use the style attribute to dynamically set CSS local variable values, overwriting CSS global variables, to dynamically adjust the style effect.