Events documentation

Stencil предлагает мощный и гибкий механизм для работы с событиями в компонентах. Важно понимать, как управлять событиями, как их генерировать, а также как обрабатывать их в компонентах.

Система событий в Stencil

Система событий в Stencil поддерживает два основных типа: собственные события (Custom Events) и стандартные DOM-события. Основной особенностью является интеграция с реактивной моделью, что позволяет синхронизировать состояние компонента с событиями.

Генерация событий

Stencil использует стандартный механизм для создания пользовательских событий, который соответствует спецификации CustomEvent. Для создания события необходимо использовать декоратор @Event. Он объявляет событие, которое будет доступно для передачи из компонента.

Пример создания события:

import { Component, Event, EventEmitter } from '@stencil/core';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Event() myCustomEvent: EventEmitter;

  handleClick() {
    this.myCustomEvent.emit('Данные, которые передаются с событием');
  }

  render() {
    return (
      <button onCl ick={() => this.handleClick()}>
        Отправить событие
      </button>
    );
  }
}

В этом примере мы создаем событие myCustomEvent, которое будет генерироваться при клике на кнопку. С помощью EventEmitter можно передавать данные вместе с событием. Эмиттирование события происходит через метод emit(), который может принимать аргументы.

Передача данных с событием

При использовании события через EventEmitter можно передавать дополнительные данные, такие как строки, объекты и даже функции. Важно отметить, что передаваемые данные можно обработать в родительском компоненте или на уровне глобальных слушателей событий.

Пример передачи данных:

@Event() dataChanged: EventEmitter;

handleDataChange() {
  this.dataChanged.emit({ value: 42, description: 'Новое значение' });
}

В родительском компоненте данные из события можно получить следующим образом:

<my-component onDataChan ged={(event) => console.log(event.detail)}></my-component>

Здесь event.detail содержит объект с переданными данными: { value: 42, description: 'Новое значение' }.

Прослушивание событий

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

Пример прослушивания события:

<my-component onMyCustomEv ent={(event) => console.log('Событие получено:', event)}></my-component>

В этом случае событие myCustomEvent будет слушаться в родительском компоненте, и при его возникновении будет выведено сообщение в консоль.

Декоратор @Event()

Декоратор @Event() является основным способом работы с событиями в Stencil. Он определяет событие, которое может быть сгенерировано компонентом. Основные параметры, которые можно использовать с декоратором:

  • @Event() eventName: EventEmitter; — объявление события.
  • bubbles (по умолчанию true) — событие будет всплывать по DOM-дереву.
  • composed (по умолчанию false) — событие может проникать за пределы Shadow DOM.
  • cancelable (по умолчанию true) — событие может быть отменено с помощью event.preventDefault().

Пример с параметрами:

@Event({ bubbles: true, composed: true }) myCustomEvent: EventEmitter;

В этом примере событие будет всплывать и будет доступно для прослушивания за пределами Shadow DOM.

Отмена события

С помощью метода preventDefault() можно отменить событие, если оно поддерживает такую возможность. Это полезно в случае, когда необходимо прервать стандартное поведение элемента.

Пример отмены события:

@Event() myEvent: EventEmitter;

handleClick() {
  const event = new CustomEvent('myEvent', { cancelable: true });
  if (someCondition) {
    event.preventDefault();  // Отменяем событие
  }
  this.myEvent.emit(event);
}

В этом примере событие будет сгенерировано, но только если не выполнено условие, оно будет отменено.

Передача обработчиков событий

Stencil позволяет передавать функции-обработчики событий через атрибуты компонента. Такой подход предоставляет большую гибкость при взаимодействии между компонентами. Обработчик события можно передать как пропс, и он будет вызываться при срабатывании события.

Пример передачи обработчика события:

<Component myEventHandler={(event) => console.log(event)}></Component>

Здесь myEventHandler — это обработчик, переданный в компонент, и он будет вызываться при срабатывании события.

Прокси-события

Stencil позволяет создавать прокси-события для более удобного управления и прослушивания событий. Прокси-события дают возможность добавлять дополнительные уровни абстракции и гибкости, позволяя перехватывать и изменять обработку событий.

Пример использования прокси-события:

@Event() proxyEvent: EventEmitter;

handleEvent() {
  this.proxyEvent.emit('данные');
}

Особенности работы с событиями в Shadow DOM

Одной из важных особенностей работы с событиями в Stencil является поддержка Shadow DOM. События, сгенерированные внутри Shadow DOM, не будут автоматически всплывать в основной документ, если не указано иное. Чтобы событие могло выйти за пределы Shadow DOM, нужно установить свойство composed в true.

Пример события, которое выходит за пределы Shadow DOM:

@Event({ composed: true }) customEvent: EventEmitter;

Если composed установлено в false, событие останется внутри компонента и не будет доступно в DOM вне компонента.

Работа с событиями и асинхронность

При работе с событиями в Stencil важно учитывать, что события генерируются синхронно, однако обработчики могут быть асинхронными. Это может быть полезно, если требуется обработка событий с задержками или выполнение операций, таких как HTTP-запросы.

Пример асинхронного обработчика:

@Event() asyncEvent: EventEmitter;

async handleAsyncEvent() {
  const data = await fetchData();
  this.asyncEvent.emit(data);
}

Взаимодействие с глобальными событиями

Stencil также позволяет работать с глобальными событиями, например, через window или document. Это может быть полезно для реализации глобальной обработки событий, таких как клавиши, прокрутка и другие.

Пример глобального события:

window.addEventListener('resize', () => {
  console.log('Размер окна изменен');
});

Это событие будет работать вне зависимости от компонентов, так как оно не привязано к конкретному элементу.

Советы по организации событий

  1. Группировка событий: Если компонент генерирует несколько событий, рекомендуется использовать одну или несколько группировок, чтобы избежать большого количества мелких событий. Например, использовать объект для передачи нескольких данных в одном событии.

  2. Использование документации: Всегда следует тщательно документировать события, особенно если они передают важную информацию, так как это улучшает поддержку и разработку в дальнейшем.

  3. Реактивность: Важно учитывать реактивность данных при работе с событиями, так как они могут быть связаны с изменениями состояния компонента.

  4. Отложенные события: При необходимости отложенной передачи события можно использовать setTimeout или requestAnimationFrame для более гибкой обработки.

Stencil предоставляет мощные инструменты для работы с событиями, которые можно адаптировать под различные сценарии и задачи, обеспечивая гибкость и расширяемость.