Интерфейсы событий

Haunted — это минималистичная библиотека для создания веб-компонентов на базе функциональных компонентов в стиле React, использующая стандарты Web Components. Одной из ключевых особенностей является работа с событиями и их интерфейсами, обеспечивающая гибкое взаимодействие компонентов и управление состоянием приложения.

Обработка событий

В Haunted события обрабатываются через стандартный механизм DOM, но с особенностями функционального подхода. Основной инструмент для привязки событий — это атрибуты внутри шаблона, создаваемого с помощью html из haunted.

import { html, component } from 'haunted';

function Counter({ count = 0 }) {
  return html`
    <div>
      <p>Счетчик: ${count}</p>
      <button @click=${() => count++}>Увеличить</button>
    </div>
  `;
}

customElements.define('my-counter', component(Counter));

Ключевое отличие от стандартного DOM в Haunted заключается в использовании @event синтаксиса для привязки обработчиков. Это упрощает работу с функциями внутри функциональных компонентов и позволяет интегрировать их с реактивным состоянием через useState.

События пользовательских компонентов

Haunted полностью поддерживает кастомные события (CustomEvent). Они создаются и отправляются стандартным образом через dispatchEvent, а слушаются либо внутри родительских компонентов, либо глобально.

function ChildComponent() {
  const handleClick = () => {
    const event = new CustomEvent('increment', { detail: 1, bubbles: true, composed: true });
    this.dispatchEvent(event);
  };

  return html`<button @click=${handleClick}>Добавить</button>`;
}

customElements.define('child-component', component(ChildComponent));

Особое внимание стоит уделить свойствам bubbles и composed. bubbles: true позволяет событию подниматься по DOM-дереву, а composed: true — проходить через Shadow DOM, что критично для модульных компонентов, встроенных в закрытые DOM-контейнеры.

Интерфейсы событий и их свойства

Все события в Haunted наследуются от стандартного Event DOM. Основные свойства и методы:

  • type — строка, указывающая тип события.
  • target — элемент, на котором событие было изначально вызвано.
  • currentTarget — элемент, на котором обработчик события был вызван.
  • bubbles — булево значение, указывающее, всплывает ли событие.
  • cancelable — возможность отмены события с помощью preventDefault().
  • composedPath() — возвращает массив элементов, через которые прошло событие.

Для CustomEvent добавляется свойство detail, содержащее произвольные данные, передаваемые вместе с событием.

Обработка событий в функциональных компонентах

Haunted предлагает функциональные хуки для работы с событиями:

  • useEvent позволяет подписываться на события с автоматическим управлением отпиской при размонтировании компонента.
  • useState в связке с событиями обеспечивает реактивное обновление интерфейса при их наступлении.

Пример интеграции хуков:

import { html, component, useState } from 'haunted';

function ClickCounter() {
  const [count, setCount] = useState(0);

  const handleIncrement = (event) => {
    setCount(count + event.detail);
  };

  return html`
    <child-component @increment=${handleIncrement}></child-component>
    <p>Итоговое значение: ${count}</p>
  `;
}

customElements.define('click-counter', component(ClickCounter));

В данном примере событие increment обрабатывается через реактивное состояние count, что полностью соответствует концепции функционального подхода Haunted.

Особенности взаимодействия с Shadow DOM

В Haunted компоненты по умолчанию создаются с Shadow DOM. Это накладывает ограничения на обработку событий:

  1. События, не имеющие composed: true, не могут выйти из Shadow DOM.
  2. События с bubbles: false не всплывают даже внутри Shadow DOM.
  3. Составные пути событий можно отслеживать через метод composedPath() для правильной маршрутизации.

Эти правила особенно важны при построении модульных интерфейсов с вложенными компонентами.

Взаимодействие нескольких компонентов

События в Haunted создают гибкую систему взаимодействия компонентов: родитель может слушать события всех дочерних элементов, дочерние компоненты могут уведомлять родителей о изменениях через CustomEvent, а глобальные события можно использовать для межкомпонентной коммуникации.

window.addEventListener('global-event', e => console.log(e.detail));

Рекомендации по организации событий

  • Использовать CustomEvent для передачи данных между компонентами.
  • Устанавливать bubbles: true и composed: true для событий, которые должны быть видимы за пределами Shadow DOM.
  • Оборачивать обработчики событий в функции, чтобы избежать лишних пересозданий при перерисовке.
  • Следить за отпиской от глобальных событий через хуки или disconnectedCallback, чтобы избежать утечек памяти.

Интерфейсы событий в Haunted обеспечивают мощный, но при этом простой механизм связи компонентов через стандартный DOM API и кастомные расширения, позволяя создавать масштабируемые, реактивные приложения на Web Components.