<div x-ref="root" id="modal2"> <div x-data="{ open: false }"> <button x-on:click="open = !open">Переключить содержимое</button> <template x-teleport="#modal2"> <div x-show="open"> Содержимое... </div> </template> </div> <div>Некоторое другое содержимое, размещённое после модальной разметки.</div></div>
x-teleport
Директива x-teleport
позволяет перенести часть шаблона Alpine целиком в другую часть DOM на странице.
Это полезно для таких вещей, как модальные окна (особенно вложенные), где полезно выйти за пределы свойства z-index текущего компонента Alpine.
Присоединяя x-teleport
к элементу <template>
, вы указываете Alpine «добавить» этот элемент к предоставленному селектору.
Пример с модальным окном:
Обратите внимание, что при переключении модала его фактическое содержимое появляется после элемента «Некоторое другое содержимое…»? Это связано с тем, что при инициализации Alpine видит x-teleport="body"
, добавляет и инициализирует этот элемент к предоставленному селектору элементов.
Переадресация событий
Alpine изо всех сил старается сделать процесс телепортации максимально комфортным. Всё, что вы обычно делаете в шаблоне, вы сможете сделать внутри шаблона x-teleport
. Телепортированный контент может получить доступ к обычной области действия компонента Alpine, а также к другим функциям, таким как $refs
, $root
и т. д.
Однако собственные события DOM не имеют понятия телепортации, поэтому, если, например, вы запускаете событие «клика» внутри телепортированного элемента, это событие всплывёт в дереве DOM, как это обычно происходит.
Чтобы сделать этот процесс более плавным, вы можете «пересылать» события, просто зарегистрировав слушатели событий в самом элементе <template x-teleport...>
следующим образом:
<div x-ref="root" id="modal3"> <div x-data="{ open: false }"> <button x-on:click="open = !open">Переключить содержимое</button> <template x-teleport="#modal3" x-on:click="open = false"> <div x-show="open"> Содержимое... <div>(нажмите чтобы закрыть)</div> </div> </template> </div></div>
Заметили, что теперь мы можем прослушивать события, отправляемые изнутри телепортированного элемента, находясь вне самого элемента <template>
?
Alpine делает это путём поиска слушателей событий, зарегистрированных в <template x-teleport...>
, и останавливает распространение этих событий за пределы живого, телепортированного элемента DOM. Затем он создает копию этого события и повторно отправляет её из <template x-teleport...>
.
Вложенное содержимое
Телепортация особенно полезна, если вы пытаетесь вложить одно модальное окно в другое. Alpine упрощает это:
<div x-ref="root" id="modal4"> <div x-data="{ open: false }"> <button x-on:click="open = !open">Переключить содержимое</button> <template x-teleport="#modal4"> <div x-show="open"> <div class="py-4">Содержимое...</div> <div x-data="{ open: false }"> <button x-on:click="open = !open">Переключить вложенное содержимое</button> <template x-teleport="#modal4"> <div class="pt-4" x-show="open"> Вложенное содержимое... </div> </template> </div> </div> </template> </div> <template x-teleport-target="modals3"></template></div>
После включения обоих модальных окон они создаются как дочерние, но будут отображаться на странице как родственные элементы, а не друг в друге.
Проверка знаний
Что нужно передавать в качестве значения директивы x-teleport
?