Stimulus строится на концепции контроллеров, связывающих поведение JavaScript с HTML-элементами. Основной инструмент для обработки событий и взаимодействия пользователя в Stimulus — это действия (actions). Они позволяют напрямую привязывать события DOM к методам контроллера, что делает код лаконичным, модульным и легко поддерживаемым.
Действие в Stimulus определяется с помощью атрибута
data-action. Формат записи:
<button data-action="событие#метод">Нажми меня</button>
событие — любое стандартное событие DOM (например,
click, input, submit).метод — метод контроллера, который будет вызван при
наступлении события.# — разделитель между событием и методом.Пример:
<div data-controller="hello">
<button data-action="click#greet">Приветствие</button>
</div>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
greet(event) {
console.log("Привет, Stimulus!");
}
}
При клике на кнопку вызывается метод greet.
Stimulus позволяет привязать несколько действий к одному элементу:
<button data-action="click#greet mouseover#highlight">Кнопка</button>
В этом примере:
click#greet вызывает метод greet при
клике;mouseover#highlight вызывает метод
highlight при наведении мыши.Порядок действий в атрибуте не имеет значения — все события обрабатываются независимо.
Метод действия всегда получает объект события DOM как первый аргумент:
greet(event) {
console.log(event.target); // элемент, вызвавший событие
console.log(event.type); // тип события
}
Важно: this внутри метода действия
ссылается на текущий экземпляр контроллера, что позволяет обращаться к
this.element или другим методам контроллера без потери
контекста.
Stimulus поддерживает модификаторы событий, упрощающие работу с распространёнными задачами:
once — обработчик срабатывает один раз;prevent — вызывает
event.preventDefault();stop — вызывает
event.stopPropagation().Примеры:
<form data-controller="form" data-action="submit->form#send prevent">
<input type="text">
<button type="submit">Отправить</button>
</form>
Метод send будет вызван при отправке формы, но
стандартное поведение формы (перезагрузка страницы) будет
предотвращено.
<button data-action="click->notifications#show once">Показать уведомление</button>
Метод show вызовется только один раз при первом
клике.
Stimulus позволяет использовать делегирование событий через CSS-селекторы, облегчая работу с динамически создаваемыми элементами:
<ul data-controller="list" data-action="click->list#selectItem">
<li data-list-target="item">Элемент 1</li>
<li data-list-target="item">Элемент 2</li>
</ul>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["item"]
selectItem(event) {
const clickedItem = event.target.closest("[data-list-target='item']")
if (!clickedItem) return
clickedItem.classList.toggle("selected")
}
}
Метод selectItem будет работать даже при добавлении
новых <li> элементов динамически, так как событие
делегировано родительскому элементу <ul>.
Stimulus позволяет связывать действия с пользовательскими событиями,
создаваемыми через dispatch:
this.element.dispatchEvent(
new CustomEvent("item:selected", { detail: { id: 42 }, bubbles: true })
)
Привязка действия к пользовательскому событию:
<div data-controller="items" data-action="item:selected->items#handleSelection"></div>
Метод контроллера получит объект события с доступом к
event.detail:
handleSelection(event) {
console.log(event.detail.id) // 42
}
Преимущества пользовательских событий:
Stimulus поддерживает специфичные модификаторы для клавиш:
<input data-action="keydown.enter->search#submit keydown.esc->search#clear">
keydown.enter — срабатывает только при нажатии клавиши
Enter.keydown.esc — срабатывает только при нажатии
Escape.Можно комбинировать модификаторы с prevent и
stop:
<input data-action="keydown.enter->search#submit prevent">
Это предотвращает стандартное поведение формы при нажатии Enter и
вызывает метод submit.
Методы действий могут быть асинхронными, что позволяет удобно
работать с fetch или другими промисами:
async loadData(event) {
event.preventDefault()
const response = await fetch("/data.json")
const data = await response.json()
console.log(data)
}
Привязка:
<button data-action="click->data#loadData">Загрузить данные</button>
preventDefault() и
stopPropagation().Stimulus делает обработку событий и взаимодействие пользователя
прямой и декларативной. Атрибут data-action превращает
стандартные события DOM в управляемые методы контроллера, сохраняя
структуру HTML и чистоту JavaScript-кода. Это обеспечивает
легкую масштабируемость и поддержку
фронтенд-приложений, где большое количество интерактивных элементов
требует аккуратной и надежной организации поведения.