Stimulus — это легковесный JavaScript-фреймворк, ориентированный на
улучшение интерактивности HTML через минимальные вмешательства в
разметку. Основной строительный блок — контроллер,
который привязывается к DOM-элементам через
data-controller. Важная особенность Stimulus —
реактивность, достигаемая через наблюдатели, которые
автоматически реагируют на изменения состояния или DOM.
Наблюдатель в Stimulus — это механизм, позволяющий контроллеру
отслеживать изменения в DOM, атрибутах или значениях свойств и
автоматически выполнять связанные действия. Реактивность обеспечивается
через связывание элементов с методами контроллера, а также через
использование специальных атрибутов
data-<controller>-target и
data-<controller>-action.
Targets — это элементы внутри контроллера, которые
можно динамически изменять или отслеживать. Они задаются через атрибут
data-<controller>-target="имя".
Пример:
<div data-controller="counter">
<span data-counter-target="output">0</span>
<button data-action="click->counter#increment">+</button>
</div>
В контроллере counter:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["output"];
increment() {
this.outputTarget.textContent = parseInt(this.outputTarget.textContent) + 1;
}
}
Ключевой момент: любое изменение через target автоматически отражается на DOM-элементе, с которым он связан, что обеспечивает базовую реактивность.
Stimulus позволяет создавать Value-объекты, которые
отслеживают изменения данных и вызывают соответствующие методы при их
обновлении. Для этого в контроллере объявляются свойства через
static values.
Пример:
export default class extends Controller {
static values = { count: Number }
connect() {
console.log(this.countValue); // значение по умолчанию
}
increment() {
this.countValue++;
}
countValueChanged() {
console.log(`Новое значение: ${this.countValue}`);
}
}
countValue — текущее значение свойства.countValueChanged — метод автоматически вызывается при
изменении значения.Особенность: Stimulus автоматически связывает value
с DOM, если используется атрибут
data-<controller>-count-value.
<div data-controller="counter" data-counter-count-value="0">
<span data-counter-target="output"></span>
</div>
События DOM привязываются к методам контроллера через атрибут
data-action. Это обеспечивает реактивную обработку
пользовательских действий без прямой манипуляции DOM.
Синтаксис:
<button data-action="click->controller#method">Click</button>
click — событие DOM.controller#method — метод контроллера, который будет
вызван.Stimulus обрабатывает события централизованно, что повышает читаемость кода и упрощает тестирование.
Для сложных сценариев, когда требуется следить за изменениями атрибутов или дочерних элементов, используются MutationObserver или сторонние библиотеки, интегрируемые с Stimulus.
Пример использования MutationObserver внутри
контроллера:
export default class extends Controller {
connect() {
this.observer = new MutationObserver(this.onMutation.bind(this));
this.observer.observe(this.element, { childList: true, subtree: true });
}
onMutation(mutations) {
mutations.forEach(mutation => {
console.log('Изменение DOM:', mutation);
});
}
disconnect() {
this.observer.disconnect();
}
}
Важно: использование наблюдателей следует ограничивать до действительно динамических элементов, чтобы не перегружать приложение.
Stimulus позволяет строить реактивные интерфейсы, комбинируя Targets, Values и Actions. Такой подход обеспечивает:
Пример полноценного счетчика:
<div data-controller="counter" data-counter-count-value="0">
<span data-counter-target="output"></span>
<button data-action="click->counter#increment">+</button>
<button data-action="click->counter#decrement">-</button>
</div>
Контроллер:
export default class extends Controller {
static targets = ["output"];
static values = { count: Number }
connect() {
this.updateOutput();
}
increment() {
this.countValue++;
}
decrement() {
this.countValue--;
}
countValueChanged() {
this.updateOutput();
}
updateOutput() {
this.outputTarget.textContent = this.countValue;
}
}
Все изменения данных автоматически отображаются в интерфейсе без дополнительных вызовов.
Эти принципы позволяют строить масштабируемые и поддерживаемые интерактивные интерфейсы на базе Stimulus с минимальной сложностью.