Morph
Плагин Morph позволяет «преобразовать» элемент на странице в предоставленный HTML-шаблон, при этом сохраняется любое состояние браузера или Alpine внутри «морфированного» элемента.
Это удобно для обновления HTML из серверного запроса без потери состояния страницы Alpine. Подобная утилита лежит в основе таких полностековых фреймворков, как Laravel Livewire и Phoenix LiveView.
Лучше всего понять его назначение можно с помощью следующей интерактивной визуализации. Попробуйте!
Установка
Вы можете использовать этот плагин, включив его из тега <script>
или установив с помощью менеджера пакетов.
Через CDN
Вы можете подключить CDN-сборку этого плагина с помощью тега <script>
, только подключать нужно ДО основного JS-файла Alpine.
Через менеджер пакетов
Вы можете установить Morph для использования внутри вашей сборки следующим образом:
Затем инициализируйте его в своей сборке:
Alpine.morph()
Функция Alpine.morph(el, newHtml)
позволяет императивно изменить узел DOM на основе переданного HTML. Она принимает следующие параметры:
Параметр | Описание |
---|---|
el | DOM-элемент на странице. |
newHtml | Строка HTML, используемая в качестве шаблона для преобразования элемента DOM. |
options (необязательный) | Объект параметров, используемый в основном для внедрения перехватчиков жизненного цикла. |
Приведём пример использования Alpine.morph()
для обновления компонента Alpine с помощью нового HTML: (В реальных приложениях этот новый HTML, скорее всего, будет поступать с сервера):
Хуки жизненного цикла
Плагин «Morph» работает путём сравнения двух деревьев DOM, живого элемента и переданного в HTML.
Morph одновременно обходит оба дерева и сравнивает каждый узел и его дочерние элементы. Если он находит различия, он «исправляет» (изменяет) текущее дерево DOM, чтобы оно соответствовало переданному в дереве HTML.
Хотя алгоритм по умолчанию очень эффективен, бывают случаи, когда вам может потребоваться подключиться к его жизненному циклу и наблюдать или изменять его поведение по мере того, как оно происходит.
Прежде чем мы перейдём к самим доступным хукам жизненного цикла, давайте сначала перечислим все потенциальные параметры, которые они получают, и объясним, что представляет собой каждый из них:
Параметр или функция | Описание |
---|---|
el | Это всегда актуальный, текущий элемент DOM на странице, который будет «исправлен» (изменен Morph). |
toEl | Это «элемент шаблона». Это временный элемент, представляющий то, к чему будет привязан живой el . Он никогда не появится на странице и должен использоваться только в справочных целях. |
childrenOnly() | Это функция, которую можно вызвать внутри хука, чтобы сообщить Morph пропустить текущий элемент и «исправить» только его дочерние элементы. |
skip() | Функция, которая при вызове внутри хука «пропускает» сравнение/исправление себя и дочерних элементов текущего элемента. |
Вот доступные хуки жизненного цикла (передаются в качестве третьего параметра в Alpine.morph(..., options)
):
Наименование хука | Описание |
---|---|
updating(el, toEl, childrenOnly, skip) | Вызывается перед исправлением el с помощью сравнения toEl . |
updated(el, toEl) | Вызывается после того, как Morph исправил el . |
removing(el, skip) | Вызывается перед тем, как Morph удаляет элемент из живого DOM. |
removed(el) | Вызывается после того, как Morph удалил элемент из действующего DOM. |
adding(el, skip) | Вызывается перед добавлением нового элемента. |
added(el) | Вызывается после добавления нового элемента в действующее дерево DOM. |
key(el) | Функция многократного использования, позволяющая определить, как Morph «ключит» элементы в дереве перед сравнением/исправлением. Подробнее об этом здесь |
lookahead | Логическое значение, указывающее Morph включить дополнительную функцию в его алгоритме, которая «заглядывает вперед», чтобы гарантировать, что элемент DOM, который собирается быть удален, вместо этого должен быть просто «перемещен» в более поздний родственный элемент. |
Вот код всех этих хуков жизненного цикла для более конкретной информации:
Ключи
Утилиты, различающие Dom, такие как Morph, изо всех сил стараются точно «преобразовать» исходный DOM в новый HTML. Однако бывают случаи, когда невозможно определить, следует ли просто заменить элемент или заменить его полностью.
Из-за этого ограничения в Morph есть «ключевая» система, которая позволяет разработчикам «принудительно» сохранять определённые элементы, а не заменять их.
Наиболее распространённым вариантом их использования является список дочерних элементов внутри цикла. Ниже приведен пример того, почему иногда необходимы ключи:
Учитывая описанную выше ситуацию, Morph не имеет возможности узнать, что узел «Ваня» был перемещен в дереве DOM. Он просто думает, что «Вася» был изменен на «Ваня», а «Ваня» изменен на «Петя».
На самом деле это не то, чего мы хотим, мы хотим, чтобы Morph сохранял исходные элементы и вместо их изменения ПЕРЕМЕЩАЛ их внутри <ul>
.
Добавляя ключи к каждому узлу, мы можем сделать это следующим образом:
Теперь, когда у элементов <li>
есть «ключи», Morph сопоставит их в обоих деревьях и переместит соответствующим образом.
Вы можете настроить то, что Morph считает «ключом», с помощью опции конфигурации key:
. Подробнее об этом здесь
Проверка знаний
-
Как внедрить перехватчики жизненного цикла с помощью функции
Alpine.morph()
? -
Какой хук вызывается перед добавлением нового элемента?