Svelte
Actions: директива use:
Подсказка-тултип, закрытие меню по клику снаружи, перетаскивание элемента - всё это поведение, привязанное к конкретному DOM-узлу. Писать его внутри компонента через bind:this и ручные слушатели значит смешивать логику узла с логикой компонента и копировать её в каждом месте, где поведение нужно. Action выносит это в отдельную функцию: она получает узел при монтировании, навешивает поведение и сама убирает его при удалении узла. Подключается одной директивой use: и переиспользуется где угодно.
- Тултип: action навешивает всплывающую подсказку на любой элемент
- Клик снаружи: action закрывает меню или модалку при клике вне узла
- Перетаскивание: action делает элемент draggable и сообщает новые координаты
- Автофокус: action ставит фокус на поле сразу после монтирования
- Ленивая загрузка: action через IntersectionObserver подгружает картинку при появлении в зоне видимости
Предварительные знания
- Компоненты и навешивание поведения на элементы разметки
- DOM API: addEventListener и removeEventListener
- Понимание того, что элемент появляется и исчезает из DOM по ходу работы приложения
Action и директива use:
Action - это обычная функция, которая первым аргументом получает DOM-узел. Svelte вызывает её, когда элемент примонтирован к странице, и передаёт сам узел. Внутри функции навешивают нужное поведение: слушатели событий, наблюдатели, начальную настройку. Подключается action директивой use: с именем функции на элементе.
Функция autofocus получает узел input и сразу вызывает на нём focus. Директива use:autofocus подключает её к полю, и при монтировании курсор оказывается в нём. Логика фокуса вынесена из компонента в отдельную функцию, которую можно подключить к любому элементу одной строкой.
Action вызывается один раз при монтировании элемента, а не при каждом обновлении. Это место для разовой настройки узла и подписки на события. Реакция на повторные изменения параметра делается через возвращаемый метод update, о котором речь дальше.
Что получает функция-action первым аргументом?
Параметры, update и destroy
Action часто подписывается на события, и эту подписку нужно убрать, когда узел удаляется со страницы, иначе остаётся утечка. Для этого action возвращает объект с методом destroy - Svelte вызовет его при размонтировании элемента. Если action принимает параметр (второй аргумент функции), он передаётся через значение в use. Метод update в возвращаемом объекте вызывается, когда параметр меняется.
Action clickOutside навешивает на документ слушатель и вызывает переданную функцию, когда клик пришёлся вне узла. Параметр - функция закрытия - передаётся через use:clickOutside в фигурных скобках. Метод destroy снимает слушатель при удалении узла, метод update обновляет ссылку на функцию, если она поменялась. Утечки слушателя не происходит.
| Часть | Когда вызывается | Для чего |
|---|---|---|
| Тело функции | При монтировании узла | Настройка и подписка |
| update | При смене параметра | Реакция на новое значение |
| destroy | При удалении узла | Очистка подписок |
Если action подписался на событие и не вернул destroy, слушатель останется после удаления узла. Это накапливает обработчики и приводит к утечкам памяти и лишним срабатываниям. Любая подписка в action должна сниматься в методе destroy.
За что отвечает метод destroy в объекте, который возвращает action?
Когда action - правильный инструмент
Action хорош, когда поведение привязано к конкретному узлу, переиспользуется и требует прямого доступа к DOM. Тултип, клик снаружи, перетаскивание, ленивая загрузка по видимости, интеграция сторонней DOM-библиотеки - типичные случаи. Логика собрана в одной функции, очистка встроена, подключение единообразно через use. Поведение легко переносится между проектами как обычный модуль.
Один файл tooltip собирает всё поведение подсказки: создание элемента, показ по наведению, обновление текста через update и полную очистку в destroy. Подключается строкой use:tooltip с текстом. Тот же модуль работает на кнопке, иконке или ссылке без изменений.
- Поведение узла внутри компонента — bind:this, ручные слушатели и очистка в эффекте. Логика смешана с компонентом и дублируется при повторном использовании
- Поведение узла в action — Одна функция с настройкой, update и destroy. Подключается через use, переиспользуется и переносится как модуль
Action - не для логики состояния приложения и не для вычислений. Это поведение, неотделимое от DOM-узла. Если задача не требует прямого доступа к узлу, обычно лучше подойдут состояние, производные значения и обработчики событий.
Какой случай лучше всего подходит для action?
Связь с другими темами
Actions работают на стыке DOM-узла и жизненного цикла:
- Компоненты — Action подключается к элементу внутри компонента директивой use
- Привязки и bind:this — Оба дают доступ к узлу, но action инкапсулирует поведение в функцию
- Жизненный цикл — Action настраивает узел при монтировании и очищает при удалении
Итог
- Action - функция, которой Svelte передаёт DOM-узел при монтировании элемента
- Подключается директивой use: на элементе, поведение навешивается прямо на переданный узел
- Action может принимать параметр вторым аргументом - значение из use
- Возвращаемый объект с методом destroy очищает поведение при удалении узла, с update реагирует на смену параметра
- Actions инкапсулируют поведение узла в переиспользуемую функцию: тултип, клик снаружи, перетаскивание
Связанные уроки
- sv-03-components — Action навешивается на элемент внутри компонента, поэтому нужна основа работы с компонентами
- sv-14-bindings — И bind:this, и action дают доступ к DOM-узлу, но action инкапсулирует поведение в переиспользуемую функцию
- sv-17-lifecycle — Action работает с жизненным циклом узла: настройка при монтировании и очистка при удалении