Эмиссия событий

Slim.js — легковесная библиотека для создания веб-компонентов с реактивным обновлением состояния и удобной работой с DOM. Одной из ключевых возможностей Slim.js является система событий, позволяющая компонентам взаимодействовать друг с другом и уведомлять внешние элементы о внутренних изменениях. Эмиссия событий играет центральную роль в построении динамических и масштабируемых приложений.


Основы событий в Slim.js

В Slim.js каждый компонент может генерировать события с помощью встроенного метода dispatchEvent. Это позволяет компоненту сигнализировать о каких-либо действиях или изменениях своего состояния. В отличие от обычных DOM-событий, события в Slim.js могут содержать детализированные данные, передаваемые через объект CustomEvent.

class CounterComponent extends Slim {
    constructor() {
        super();
        this.count = 0;
    }

    increment() {
        this.count++;
        this.dispatchEvent(new CustomEvent('countChanged', {
            detail: { value: this.count },
            bubbles: true
        }));
    }

    get template() {
        return `<button oncl ick="this.increment()">Increment</button>
                <span>${this.count}</span>`;
    }
}

Slim.tag('counter-component', CounterComponent);

В этом примере метод increment увеличивает счётчик и генерирует событие countChanged. В объекте detail передаётся текущее значение счётчика. Опция bubbles: true обеспечивает возможность “всплытия” события до родительских элементов, что облегчает управление поведением на уровне контейнера.


Слушатели событий

Для обработки событий, эмитируемых компонентом, можно использовать стандартные методы DOM: addEventListener. Slim.js позволяет легко подписываться на события компонентов как внутри других компонентов, так и в обычном HTML.

document.querySelector('counter-component')
        .addEventListener('countChanged', (event) => {
            console.log('Новое значение счетчика:', event.detail.value);
        });

Внутри другого компонента можно подписаться на события дочернего элемента с использованием метода querySelector или динамически через цикл. Это обеспечивает гибкую архитектуру взаимодействия компонентов.


Кастомизация событий

Slim.js позволяет определять кастомные события с любыми данными и поведением. Помимо bubbles, существуют следующие важные параметры:

  • composed — разрешает событию проходить через Shadow DOM.
  • cancelable — позволяет остановить действие события с помощью event.preventDefault().

Пример:

this.dispatchEvent(new CustomEvent('actionPerformed', {
    detail: { action: 'save' },
    bubbles: true,
    composed: true,
    cancelable: true
}));

Использование composed: true важно, когда компонент находится внутри Shadow DOM, и требуется, чтобы событие достигло родительского документа или компонента-оболочки.


Связь событий с реактивными свойствами

Slim.js поддерживает реактивные свойства, которые автоматически обновляют DOM при изменении значения. Эмиссия событий часто используется в сочетании с реактивными свойствами для уведомления других компонентов о изменении состояния.

class ToggleComponent extends Slim {
    constructor() {
        super();
        this.active = false;
    }

    toggle() {
        this.active = !this.active;
        this.dispatchEvent(new CustomEvent('toggled', { detail: { active: this.active }, bubbles: true }));
    }

    get template() {
        return `<button oncl ick="this.toggle()">
                    ${this.active ? 'ON' : 'OFF'}
                </button>`;
    }
}

Slim.tag('toggle-component', ToggleComponent);

Событие toggled можно использовать для синхронизации состояния других компонентов или выполнения сторонних действий при изменении значения active.


Практические шаблоны использования событий

  1. Композиция компонентов Родительский компонент может реагировать на события от дочерних элементов и менять своё состояние.
class ParentComponent extends Slim {
    constructor() {
        super();
        this.status = 'inactive';
    }

    onToggle(event) {
        this.status = event.detail.active ? 'active' : 'inactive';
    }

    get template() {
        return `<toggle-component on:toggled="onToggle(event)"></toggle-component>
                <span>Status: ${this.status}</span>`;
    }
}

Slim.tag('parent-component', ParentComponent);
  1. Всплытие событий для глобального управления Использование bubbles: true и composed: true позволяет компонентам уведомлять об изменениях глобальные слушатели без прямого связывания компонентов.

  2. События с отменой действия Опция cancelable: true позволяет создавать события, которые могут быть перехвачены для предотвращения выполнения стандартной логики:

let event = new CustomEvent('beforeDelete', { cancelable: true });
if (!this.dispatchEvent(event)) {
    console.log('Удаление отменено');
}

Советы по эффективной эмиссии событий

  • Стараться разделять события на уровни ответственности: локальные события для внутренних изменений компонента и глобальные — для межкомпонентного взаимодействия.
  • Передавать структурированные данные в detail вместо использования глобальных переменных.
  • Использовать имена событий в стиле kebab-case, чтобы избежать конфликтов и соответствовать стандартам DOM.
  • Воспользоваться bubbles и composed только там, где это действительно необходимо, чтобы не перегружать дерево событий.

Эмиссия событий в Slim.js предоставляет гибкий механизм для построения реактивных интерфейсов и взаимодействия компонентов. Правильная организация событийной логики упрощает сопровождение приложения и повышает масштабируемость.