Teleport
Встроенный компонент, который позволяет нам «телепортировать» часть шаблона компонента в узел DOM, который существует вне иерархии DOM этого компонента.
Основное использование
Иногда мы можем столкнуться со следующей ситуацией: часть шаблона компонента логически принадлежит ему, но с визуальной точки зрения она должна отображаться где-то еще в DOM, вне приложения Vue
Самый распространенный пример — создание полноэкранного модального окна. В идеале мы хотим, чтобы кнопка модального окна и само модальное окно находились в одном и том же компоненте, поскольку они оба связаны с состоянием открытия/закрытия модального окна. Но это означает, что модальное окно будет отображаться рядом с кнопкой, глубоко вложенной в иерархию DOM приложения. Это может создать некоторые сложные проблемы при позиционировании модального окна с помощью CSS
Рассмотрим следующую структуру HTML
А вот реализация MyModal
Компонент содержит элемент button для запуска открытия модального окна и div класс .modal, который будет содержать содержимое модального окна и кнопку для самостоятельного закрытия
При использовании этого компонента внутри исходной структуры HTML существует ряд потенциальных проблем
- position: fixed только размещает элемент относительно области просмотра, если ни один элемент-предок не имеет или transform не установлено свойство. Если, например, мы собираемся анимировать предка с помощью преобразования CSS, это нарушит модальный макет perspective filter div class="outer"
- Модальное окно z-index ограничено содержащимися в нем элементами. Если есть другой элемент, который перекрывается с div class="outer" более высоким значением z-index, он будет перекрывать наше модальное окно
Teleport предоставляет простой способ обойти эти проблемы, позволяя нам выйти из вложенной структуры DOM. Давайте изменим, MyModal чтобы использовать Teleport
Цель to ожидает Teleport строку селектора CSS или фактический узел DOM. Здесь мы, по сути, говорим Vue «телепортировать этот фрагмент шаблона в тег body».
Важно
Цель телепорта toдолжна быть уже в DOM, когда Teleport компонент установлен. В идеале это должен быть элемент вне всего приложения Vue. Если вы нацелены на другой элемент, отображаемый Vue, вам необходимо убедиться, что этот элемент смонтирован до Teleport
Использование с компонентами
Teleport изменяет только визуализированную структуру DOM, но не влияет на логическую иерархию компонентов. То есть, если он Teleport содержит компонент, этот компонент останется логическим дочерним элементом родительского компонента, содержащего файл Teleport. Передача реквизитов и генерация событий продолжат работать таким же образом
Это также означает, что инъекции из родительского компонента работают должным образом и что дочерний компонент будет вложен ниже родительского компонента в Vue Devtools, а не там, куда переместился фактический контент.
Отключение телепорта
В некоторых случаях мы можем захотеть условно отключить Teleport. Например, мы можем захотеть отобразить компонент в виде наложения для настольных компьютеров, но встроенного на мобильных устройствах. Teleport поддерживает disabled опору, которую можно динамически переключать:
Где isMobile состояние может динамически обновляться путем обнаружения изменений медиа-запросов.
Несколько телепортов на одну цель
Распространенным вариантом использования будет многократно используемый Modal компонент с возможностью одновременной активности нескольких экземпляров. В этом случае несколько Teleport компонентов могут подключить свое содержимое к одному и тому же целевому элементу. Порядок будет простым добавлением — более поздние монтирования будут располагаться после более ранних внутри целевого элемента.
Учитывая следующее использование
Отрисованный результат будет