EventEmitter и декоратор @Event

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

Основы EventEmitter

EventEmitter в Stencil используется для создания событий в компонентах. Это класс, который предоставляет методы для регистрации и отправки событий. В Stencil для этого используется декоратор @Event.

Создание и использование EventEmitter

Каждое событие в Stencil должно быть связано с каким-либо действием в компоненте. Чтобы создать событие, необходимо использовать декоратор @Event, который объявляет событие и связывает его с компонентом.

Пример создания события с использованием @Event:

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

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

  @Event() customEvent: EventEmitter;

  triggerEvent() {
    this.customEvent.emit({ message: 'Привет от компонента!' });
  }

  render() {
    return (
      <button onCl ick={() => this.triggerEvent()}>Сгенерировать событие</button>
    );
  }
}

В этом примере создается событие customEvent, которое будет эмиттироваться при нажатии на кнопку. Когда кнопка нажимается, вызывается метод triggerEvent(), который генерирует событие с дополнительными данными — объектом с сообщением.

Работа с данными события

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

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

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

<my-component onCustomEv ent={(event) => console.log(event.detail.message)}></my-component>

Здесь event.detail будет содержать данные, переданные при эмитировании события, в данном случае сообщение “Привет от компонента!”.

Декоратор @Event

Декоратор @Event используется для создания события и подключения его к экземпляру компонента. Он позволяет задать имя события и тип данных, которые оно будет передавать. Этот декоратор может принимать различные параметры для более гибкой настройки событий.

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

@Event({
  eventName: 'customEvent', 
  bubbles: true,
  cancelable: true,
  composed: true
}) 
customEvent: EventEmitter;

Здесь:

  • eventName: задает имя события. Это имя будет использоваться для подписки на событие.
  • bubbles: указывает, должно ли событие всплывать в DOM. Если true, событие будет всплывать до родительских элементов.
  • cancelable: указывает, можно ли отменить событие с помощью метода event.preventDefault().
  • composed: указывает, может ли событие пересекать границы Shadow DOM.

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

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

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

@Component({
  tag: 'my-custom-component',
  styleUrl: 'my-custom-component.css',
  shadow: true
})
export class MyCustomComponent {

  @Event({
    eventName: 'userLoggedIn',
    bubbles: true,
    cancelable: true,
    composed: true
  }) userLoggedIn: EventEmitter;

  loginUser() {
    const user = { id: 1, name: 'Иван' };
    this.userLoggedIn.emit(user);
  }

  render() {
    return (
      <button onCl ick={() => this.loginUser()}>Войти</button>
    );
  }
}

В данном примере создается событие userLoggedIn, которое передает объект пользователя при вызове метода loginUser. Это событие можно будет использовать для выполнения действия, например, обновления состояния авторизации в другом компоненте.

Подписка на события

Чтобы подписаться на событие, можно использовать стандартный подход через атрибуты HTML. Когда событие с заданным именем возникает, срабатывает обработчик, указанный в атрибуте компонента.

Пример:

<my-custom-component onUserLogge dIn={(event) => console.log(event.detail)}></my-custom-component>

Здесь при возникновении события userLoggedIn будет выведен объект пользователя, переданный через event.detail.

Заключение

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