В Slim.js управление событиями построено на реактивной архитектуре компонентов, где каждый компонент может отслеживать изменения состояния и реагировать на пользовательские действия. Одной из ключевых задач является организация взаимодействия между компонентами, особенно передача событий от дочернего компонента к родительскому.
Slim.js использует стандартную модель DOM-событий, но добавляет
удобный синтаксис для работы с компонентами. События могут быть
кастомными (CustomEvent) и привязываться к элементам
через директиву @event в шаблоне. Важно различать два
уровня:
Для передачи данных родителю используется класс
CustomEvent. Пример:
import { Slim } from 'slim-js';
class ChildComponent extends Slim {
constructor() {
super();
this.message = 'Привет от потомка';
}
sendMessage() {
this.dispatchEvent(new CustomEvent('child-message', {
detail: { text: this.message },
bubbles: true, // позволяет событию всплывать к родителю
composed: true // разрешает прохождение через Shadow DOM
}));
}
get template() {
return `<button @click="sendMessage">Отправить сообщение</button>`;
}
}
Slim.define('child-component', ChildComponent);
Ключевые моменты:
bubbles: true — событие поднимается вверх по
DOM-дереву, что позволяет родителю его перехватить.composed: true — событие может проходить через границы
Shadow DOM, если компонент инкапсулирован.detail — объект, содержащий данные, которые необходимо
передать.Родительский компонент может слушать события дочернего компонента через стандартный синтаксис Slim.js:
import { Slim } from 'slim-js';
class ParentComponent extends Slim {
handleChildMessage(event) {
console.log('Сообщение от потомка:', event.detail.text);
}
get template() {
return `
<child-component @child-message="handleChildMessage"></child-component>
`;
}
}
Slim.define('parent-component', ParentComponent);
Особенности:
@child-message="handleChildMessage"
автоматически привязывает метод к событию.event.detail содержит данные, переданные из
потомка.Если структура компонентов вложенная, события можно передавать через
промежуточные компоненты. Для этого важно правильно настроить
bubbles и composed:
this.dispatchEvent(new CustomEvent('child-message', {
detail: { text: 'Данные' },
bubbles: true,
composed: true
}));
Любой компонент выше по дереву, который слушает
@child-message, сможет получить событие, независимо от
того, находится ли оно за Shadow DOM.
Slim.js поддерживает реактивные свойства, что позволяет родителю изменять состояние дочернего компонента через события:
class ChildComponent extends Slim {
message = '';
updateMessage(newMessage) {
this.message = newMessage;
}
get template() {
return `<div>Сообщение: ${this.message}</div>`;
}
}
class ParentComponent extends Slim {
handleChildMessage(event) {
const child = this.querySelector('child-component');
child.updateMessage(event.detail.text + ' (обновлено родителем)');
}
get template() {
return `<child-component @child-message="handleChildMessage"></child-component>`;
}
}
Таким образом, Slim.js обеспечивает двустороннюю коммуникацию без необходимости прямого обращения к внутренним методам компонента через сложные референсы.
bubbles: true для событий, которые
должны быть видны родителю.composed: true, если компоненты используют
Shadow DOM.child-message, item-selected.detail, предпочтительно передавать минимальный набор
данных.Передача событий от потомка к родителю в Slim.js строится на сочетании реактивных свойств и кастомных событий, что позволяет создавать чистую и предсказуемую архитектуру компонентов, минимизируя зависимости между ними.