Скрытый божественный компонент «ElementUI, которого вы не знаете»: Поппер и его экономка

внешний интерфейс Vue.js
Скрытый божественный компонент «ElementUI, которого вы не знаете»: Поппер и его экономка

Прочтите эту статью 📖

Ты будешь:

  • знаю дваElementUIОфициальная документация не документирована, но компонент действительно собран.
  • научитесь ими пользоваться и получитеdemoодна порция.
  • К пониманиюElementUIОсновной принцип компонента всплывающего слоя, если вы захотите разобраться с ним позжеappendToBodyи связанные с этим вопросы.

Серия "ElementUI, которого вы не знаете"

Эта серия войдет вElementUI, предоставляя вам только некоторыеElementUI«Знания уровня Бога», которые знают только опытные пользователи и даже разработчики кода.
Они очень полезны независимо от того, используются ли они в повседневной работе или во время интервью.
Также: Эта серия также подходит дляElement Plusпользователей смотрят, потому чтоElementОсновной принцип существенно не изменился.

один,ElementUIДва режима для всех всплывающих слоев в

ElementUIвсплывающие слои (включая, но не ограничиваясь:dialog, select, popover, date-pickerи т.д.) Существует два способа реализации позиционирования элементов, а именно:

  • Вариант первый:append-to-bodyРежим. В этом режиме всплывающий слой будет размещен на<body>элемент, черезposition:fixedпозиционирование, с динамическимtopа такжеleftатрибут для завершения позиционирования всплывающего элемента.
  • Второй вариант: нетappend-to-bodyРежим. В этом режиме всплывающий слой проходит черезposition:absoluteПозиционируется так, чтобы соответствовать его родительскому элементуposition:relativeдля завершения позиционирования всплывающего элемента.

В большинстве случаевElementUIВсе используются по умолчанию." Вариант 1:append-to-bodyРежим".
Причина очень проста, потому что «Вариант 2: не-append-to-bodyСуществуют серьезные побочные эффекты, и их следует использовать только в случае крайней необходимости.

Например, когда родительский элемент всплывающего компонента имеетposition: relative; overflow: autoстиль, будь тоappend-to-bodyМожет напрямую влиять на отображение компонентов:

非append-to-body模式的副作用

Образец кода:GitHub.com/Начало розыгрыша…

Почему бы нетappend-to-bodyрежим" вызовет эту проблему, в то время как "append-to-bodyрежим' не будет? Это базовый вопрос CSS, добро пожаловать в комментарии.

В дополнение к вышеперечисленным сценариям «не-append-to-bodyMode» также может вызвать аналогичные проблемы в различных сценариях.

Вот почемуElementUIустановит для всех всплывающих слоев значение "append-to-bodyшаблон" первопричина.

два,ElementUIкак управляются всплывающие окнаz-indexиз?

О первом разделе говорилось, если не указано иное,ElementUIбудет автоматически использовать "append-to-bodyРежим «для реализации всплывающего слоя.
В этой предпосылке вы могли бы также притвориться, что выElementUIразработчики, как бы вы добились следующего:

  • как гарантироватьdialogкомпонент,selectВсплывающий слой компонента выше, чемdialogвсплывающий слой?
  • как гарантироватьdialog-1Выскочил сноваdialog-2уровень выше, чемdialog-1уровень?

ElementUIКогда проектная группа разрабатывала эту часть, они придумали простое, но удивительное решение:Пока новый всплывающий слой всегда выше всех предыдущих всплывающих слоев, не будет такой вещи, как «новый всплывающий слой», покрытый «старым всплывающим слоем».

Предположим сценарий: нажмите кнопку «Всплывающее окно-1», чтобы открыть всплывающее окно «Всплывающее окно-2», а на «Всплывающее окно-2» есть «компонент раскрывающегося списка». ихz-indexКаким он будет?

嵌套层级关系

Как показано на рисунке выше, каждый раз, когда всплывающий слой всплывает, он находится на текущем максимуме.z-indexна основе+1, вы можете гарантировать, что ни один всплывающий слой не будет заблокирован без причины.

Запомните этот механизм, онElementUIОсновной механизм реализации всплывающего слоя.

Итак, кто будет управлять всем проектом?z-indexчто о?

конечно--popup管家Ла~

3. Знакомство: PopupManager

Когда Бэтмен сражается со всевозможными злодеями в Готэм-сити, его старый дворецкий Альфред всегда может помочь ему устроить тыл.

ElementUI, за всеми всплывающими слоями стоит такая работящая старая домработница, этоPopupManager.

PopupManager: Предоставляет всплывающему слою различные возможности, такие как получение экземпляров, регистрация и отмена, но его наиболее важной функцией является предоставлениеz-indexвозможности управления уровнем.

Как это использовать?

<template>
  <div>
    <el-button @click="onClick">增加</el-button>
    z-index: {{ value }} </div>
</template>
<script>
import { PopupManager } from 'element-ui/src/utils/popup'
export default {
  data() {
    return {
      value: 0
    }
  },
  methods: {
    onClick() {
      // 没错,使用起来就是这么简单,只要一行
      this.value = PopupManager.nextZIndex()
    }
  }
}
</script>

Эффект следующий:

PopupManager.nextZIndex()

Вы нашли это, в первый разPopupManager.nextZIndex()вернет 2000, тогда каждый щелчок будет+1.

Последующий+1Понятно, что самая последняя доступная информация должна быть получена каждый раз, когда всплывающий слойz-indexЭто не более чем раньше1.

Но почему в первую очередь будет2000Шерстяная ткань?

На самом деле этоElementUIВстроенный «всплывающий слой»z-indexМощность», но его можно модифицировать.

во время установкиElementUI, можно сделать встроенный2000стали3000.

// 这可以让弹出层的 z-index 从 3000 开始递增
Vue.use(Element, { zIndex: 3000 });

Знать роль старой экономки — это не просто пониматьElementUIизz-indexМеханизм управления настолько прост, что может быть очень полезен в реальном производстве и проектах.

Образец кода:GitHub.com/Начало розыгрыша…

В-четвертых, реальный бой: более гибкая полноэкранная составляющая.

Хотя официальный полноэкранный API хорош, продакт-менеджер сказал, что официалы в делах не разбираются.

Как мы все знаем, браузер имеет официальный полноэкранный API:Element.requestFullscreen(), что позволяет элементу сразу заполнить область просмотра и разместиться поверх всех элементов.

Хотя выглядит красивоAPI, но у продакт-менеджера всегда какие-то странные требования: "Эта страница поддерживает полноэкранный режим, а потом на ней какие-то всплывающие окна, а во всплывающих окнах какие-то сложные формы..."

Я оцепенел, когда услышал это:

«Официальный полноэкранный режим — это уровень настройки выше всего остального, теappend-to-bodyвсплывающее окно независимо отz-indexКаким бы высоким он ни был, его абсолютно невозможно отобразить. "

«А те, кто неappend-to-bodyВсплывающий слой режима не соответствует требованиям в некоторых бизнес-сценариях. )”

Подумав об этом, мы должны инкапсулировать «соответствие»ElementUIИерархический стандартный полноэкранный компонент".

Идея проста:实现全屏的基本思路

Это в основном то же самое, что и официальный API браузера для полноэкранного режима, но разница заключается в следующем:

  • Официальный полноэкранный режим по умолчанию будет сверху, а z-индекс будет бесконечным.
  • Полный экран инкапсулирован сам по себе, z-index соответствуетPopupManagerСпецификация Батлера.

Поэтому я написалпотрепанныйдвадцать строкdemo:

<template>
<div :class="{ 'my-full-screen': isFullScreen }" :style="{zIndex: currentZIndex}">
  <slot></slot>
</div>
</template>
<script>
import { PopupManager } from 'element-ui/src/utils/popup'

export default {
  data() {
    return {
      isFullScreen: false,
      currentZIndex: null
    }
  },
  methods: {
    request() {
      this.isFullScreen = true
      this.currentZIndex = PopupManager.nextZIndex()
    }
  }
}
</script>
<style>
.my-full-screen {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  width: 100% !important;
  height: 100% !important;
}
</style>

Эффект сравнивается с официальным API браузера:

Хотя эффект определенно не так хорош, как официальный прямой полноэкранный режим, самоупакованные также должны сотрудничать с ручнымF11, но полностью подтверждает проблему:

PopupManagerЕго можно использовать в производстве и решать практические задачи.

Образец кода:GitHub.com/Начало розыгрыша…

Пять, понимание: универсальный всплывающий компонент (vue-popper)

Хотя дворецкий Фу очень силен, Бэтмен не может ездить на Фу, чтобы сражаться. Отсюда и Бэтмобиль.

vue-popperЭто «Бэтмобиль». Никакого преувеличения.
все, что мы можем достичь,ElementUIБольшинство всплывающих слоев вvue-popperКомпоненты реализованы.

Просто перечислить:select,date-picker族,级联cascader,dropdown,popover,tooltip...и так далее, эти компоненты основаны наvue-popperКомпоненты для реализации всплывающих слоев.

Такvue-popperКак это использовать?

Вообще говоря, его основное использование混入(mixins). Три шага к использованию:

vue-popper用法三步走

Самый типичный пример, много кода перечислять не буду, можете глянутьElementUI dropdown-menuконкретное его использование. См. код:GitHub.com/E?Fe/Голодный…

Пример микширования слишком сложен, есть лине смешивай, а как насчет использования его непосредственно в качестве компонента?

Конечно, есть!

5. Настоящий бой: полностью настраиваемый всплывающий слой

как использоватьvue-popperНапишите простой «настраиваемый всплывающий слой»demo.

Выполните следующие три шага:

  1. Сначала мы вводимvue-popper, укажите ссылку на компонент в шаблоне и определите элемент всплывающего слоя и элемент позиционирования.
<template>
  <!-- 定位元素 -->
  <div class="my-picker">
    <!-- vue-popper组件 -->
    <Popper ref="popper" v-model="showPopper">
    </Popper>
    <!-- 弹出组件 -->
    <div ref="fly-piece" v-show="showPopper" class="my-picker__popper">你看,我弹出来了</div>
  </div>
</template>
<script>
// 引入vue-popper组件
import Popper from 'element-ui/src/utils/vue-popper';

export default {
  components: {
    Popper
  },
  data() {
    return {
      // 双向绑定,控制弹出层是否弹出
      showPopper: false
    },
  },
}
</script>
  1. Датьvue-popperконкретный экземплярВсплывающий слойа такжеслой позиционирования.
mounted() {
  this.$refs.popper.popperElm = this.$refs['fly-piece'];
  this.$refs.popper.referenceElm = this.$el;
}
  1. контролируяvue-popperизprops.valueчтобы контролировать, всплывает он или нет.
this.showPopper = !this.showPopper

Можно добиться следующих эффектов:简易弹出层

Разве это не просто?

Полезен ли этот компонент, если вы хотите реализовать некоторые пользовательские сложные компоненты?

Образец кода:GitHub.com/Начало розыгрыша…

Суммировать

Хорошо, давайте вспомним, о каких точках знаний мы говорили в этой статье:

  1. ElementUIДва режима всплывающих слоев и их реализация.
  2. ElementUIКак управлять всплывающими окнамиz-index.
  3. PopupManagerиспользование и практика.
  4. vue-popperиспользование и практика.