Представлена ​​технология Element-UI (4) — проектирование и реализация компонентов контейнера макета контейнера.

внешний интерфейс Vue.js внешний фреймворк

предисловие

В предыдущей статье мы разобрали дизайн и реализацию компонента Layout, а сценарий его применения обычно представляет собой частичную верстку. Для макета всей страницы,element-uiпри условииContainerКомпонент контейнера макета специально используется для общего макета фоновой страницы управления ПК.

анализ спроса

Давайте сначала посмотрим на общий макет страницы через несколько картинок.

Компоновка этих двух диаграмм очень распространена в бэкэнд-системе и может быть достигнута с помощью простого CSS. Однако мы предпочитаем использовать компонентный метод разработки для инкапсуляции этих деталей CSS в компоненты следующим образом:

<el-container>
  <el-header>Header</el-header>
  <el-main>Main</el-main>
  <el-footer>Footer</el-footer>
</el-container>

<el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-container>
      <el-main>Main</el-main>
      <el-footer>Footer</el-footer>
    </el-container>
  </el-container>
</el-container>

мы использовали<el-container>,<el-header>,<el-main>,<el-footer>,<el-aside>5 компонентов, давайте посмотрим на их соответствующие роли:

  • <el-container>: Внешний контейнер. Когда дочерний элемент содержит<el-header>или<el-footer>Когда все подэлементы вертикально расположены вертикально, в противном случае они будут расположены горизонтально.

  • <el-header>: Верхний барный контейнер.

  • <el-aside>: Контейнер боковой панели.

  • <el-main>: Контейнер основной области.

  • <el-footer>: Нижний барный контейнер.

На эти компоненты распространяются следующие ограничения:

<el-container>Дочерними элементами могут быть только последние четыре, а родительскими элементами последних четырех могут быть только<el-container>.

понялelement-uiКонтейнер Изложив требования к компоненту-контейнеру, давайте проанализируем его дизайн и реализацию.​

дизайн и реализация

Для макета диаграммы мы можем легко добиться этого с помощью гибкого макета,element-uiОн также реализован на основе гибкой верстки, далее разберем реализацию каждого компонента.

Компонент ElContainer

Сначала посмотрите на часть шаблона:

<template>
  <section class="el-container">
    <slot></slot>
  </section>
</template>

<el-container>Компонент будет отображаться как<section>маркировка и пропускslotЗаймитесь распространением контента.

Давайте снова посмотрим на часть CSS:

@include b(container) {
  display: flex;
  flex-direction: row;
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  min-width: 0;
}

Сосредоточьтесь на разделе CSS,display:flexсоздает гибкий контейнер,flex-direction:rowУказывает, что внутренние элементы располагаются в горизонтальном направлении. Почему до сих порflex:1Ну, потому что<el-container>Контейнеры поддерживают вложенность, и мы знаем, чтоflex:1эквивалентноflex-grow:1;flex-shrink:1;flex-basis:0, то есть когда<el-container>При вложении он заполняет оставшееся пространство.flex-basis:autoНастало время зарезервировать пространство вашего собственного размера контента перед местом для распространения, а затем оставшееся пространство будет возвращено оставшемуся пространству.

<el-container>Контейнер по умолчанию расположен горизонтально, конечно, он также должен поддерживать вертикальное расположение, мы можем предоставить компонент сdirectionизprop, если входящийdirectionдаvertical, добавьте соответствующий CSS.

<template>
  <section class="el-container" :class="{ 'is-vertical': isVertical }">
    <slot></slot>
  </section>
</template>
export default {
  name: 'ElContainer',

  componentName: 'ElContainer',

  props: {
    direction: String
  },

  computed: {
    isVertical() {
      if (this.direction === 'vertical') {
        return true;
      } else if (this.direction === 'horizontal') {
        return false;
      }
    }
  }
};
@include when(vertical) {
  flex-direction: column;
}

Если входящийdirectionдляverticalЗатем добавьтеis-verticalCSS, наконец, модифицируяflex-direction:columnУчтите, что внутренние элементы расположены в вертикальном направлении.

Просмотрите предыдущее требование: когда<el-container>Дочерние элементы контейнера содержат<el-header>или<el-footer>, все дочерние элементы будут расположены вертикально вверх и вниз, иначе они будут расположены горизонтально и влево.

Реализовать его также легко, расширяя вычисляемые свойстваisVerticalУсловие суждения может быть:

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; 
  }
}

Вот небольшая хитрость,this.$slots.defaultПолучает все слоты по умолчаниюvnodesузлов, а затем пройти через них черезvnode.componentOptions.tagсудить об этомvnodeне так ли<el-header>или<el-footer>.vnode.componentOptionsЕго нет в официальном API веб-сайта, но он знаком тем, кто знаком с исходным кодом Vue.

Компонент ElHeader

Давайте сначала посмотрим на часть шаблона:

<template>
  <header class="el-header">
    <slot></slot>
  </header>
</template>

<el-header>Компонент будет отображаться как<header>маркировка и пропускslotЗаймитесь распространением контента.

Давайте снова посмотрим на часть CSS:

@include b(header) {
  padding: $--header-padding;
  box-sizing: border-box;
  flex-shrink: 0;
}

в$--header-paddingявляется переменной вpackages/theme-chalk/src/common/var.scssопределяется в файле.flex-shrink: 0Указывает, что он не будет сжиматься, даже если места недостаточно<el-header>занятое пространство.

Обычно голова будет иметь фиксированную высоту, поэтому<el-header>позволяет пройти вheightизpropsчтобы указать высоту, или укажите высоту по умолчанию, если она не указана.

<template>
  <header class="el-header" :style="{ height }">
    <slot></slot>
  </header>
</template>
export default {
  name: 'ElHeader',

  componentName: 'ElHeader',

  props: {
    height: {
      type: String,
      default: '60px'
    }
  }
};

из-за прямого:styleУстановите стиль, поэтому вы должны нести блок при прохождении высоты здесь.

Компонент ElMain

Давайте сначала посмотрим на часть шаблона:

<template>
  <main class="el-main">
    <slot></slot>
  </main>
</template>

<el-main>Компонент будет отображаться как<main>маркировка и пропускslotЗаймитесь распространением контента.

Давайте снова посмотрим на часть CSS:

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

Уведомление,<main>Вкладки частично поддерживаются в IE11. как правило<main>Содержимое, завернутое в него, полностью определяется его дочерними элементами, поэтому высота и ширина не устанавливаются, простоflex:1назначить<el-container>Оставшееся пространство контейнера.

Компонент ElFooter

Давайте сначала посмотрим на часть шаблона:

<template>
  <footer class="el-footer">
    <slot></slot>
  </footer>
</template>

<el-footer>Компонент будет отображаться как<footer>маркировка и пропускslotЗаймитесь распространением контента.

Давайте снова посмотрим на часть CSS:

@include b(footer) {
  padding: $--footer-padding;
  box-sizing: border-box;
  flex-shrink: 0;
}

Как и голова, нижняя часть обычно имеет фиксированную высоту, поэтому<el-footer>позволяет пройти вheightизpropsчтобы указать высоту, или укажите высоту по умолчанию, если она не указана.

<template>
  <footer class="el-footer" :style="{ height }">
    <slot></slot>
  </footer>
</template>
export default {
  name: 'ElFooter',

  componentName: 'ElFooter',

  props: {
    height: {
      type: String,
      default: '60px'
    }
  }
};

Компоненты ElAside

Давайте сначала посмотрим на часть шаблона:

<template>
  <aside class="el-aside">
    <slot></slot>
  </aside>
</template>

<el-aside>Компонент будет отображаться как<aside>маркировка и пропускslotЗаймитесь распространением контента.

Давайте снова посмотрим на часть CSS:

@include b(aside) {
  overflow: auto;
  box-sizing: border-box;
  flex-shrink: 0;
}

<el-aside>Компоненты используются для отображения боковых панелей, а боковые панели обычно имеют ширину, поэтому<el-aside>, что позволяет пройти вwidthизpropsчтобы указать ширину, или укажите ширину по умолчанию, если она не указана.

<template>
  <aside class="el-aside" :style="{ width }">
    <slot></slot>
  </aside>
</template>
export default {
  name: 'ElAside',

  componentName: 'ElAside',

  props: {
    width: {
      type: String,
      default: '300px'
    }
  }
};

Суммировать

element-uiизContainerРеализация компонента контейнера макета по-прежнему очень проста: создаются какие-то семантические метки, контент распределяется с помощью слотов, а эффект макета достигается за счет flex.

Изучив эту статью, вы сможете, между прочим, ознакомиться с гибкой компоновкой и семантическими тегами HTML5, углубить свое понимание и узнать несколько советов по исходному коду Vue.

Если вы узнаете то, чего не знаете, вы добьетесь прогресса Если вы найдете этот тип статей полезным, вы можете порекомендовать его своим друзьям.

Следующий предварительный просмотр: технология Element-UI показывает (5) цветов, шрифтов, границ и значков.

Кроме того, я только недавно открыл публичный аккаунт "Фронтенд-частная кухня Лао Хуанга". Серия статей "Раскрытая технология Element-UI" будет обновлена ​​и опубликована в публичном аккаунте как можно скорее. Кроме того, я буду часто делитесь передовыми передовыми знаниями, галантерейными товарами и иногда делитесь некоторыми навыками мягкого качества, приглашаем всех обратить внимание ~