Перейти к содержимому

x-teleport

Директива x-teleport позволяет перенести часть шаблона Alpine целиком в другую часть DOM на странице.

Это полезно для таких вещей, как модальные окна (особенно вложенные), где полезно выйти за пределы свойства z-index текущего компонента Alpine.

Присоединяя x-teleport к элементу <template>, вы указываете Alpine «добавить» этот элемент к предоставленному селектору.

Пример с модальным окном:

<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>
Некоторое другое содержимое, размещённое после модальной разметки.

Обратите внимание, что при переключении модала его фактическое содержимое появляется после элемента «Некоторое другое содержимое…»? Это связано с тем, что при инициализации 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?