See how Stencil fits into the entire Ionic Ecosystem ->
Stencil is part of the Ionic Ecosystem ->

イベント

stencil eventsのようなものはありません。代わりに、StencilはDOMイベントの使用を推奨しています。 ただし、Stencilは、コンポーネントが発行できるイベントと、コンポーネントがリッスンするイベントを指定するためのAPIを提供します。 これは、 Event()および Listen()デコレータを使用して行われます。

イベントデコレータ

コンポーネントは、イベントエミッタデコレータを使用してデータとイベントを発行できます。

カスタムDOMイベントをディスパッチして他のコンポーネントを処理するには、@Event()デコレータを使用します。

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

...
export class TodoList {

  @Event() todoCompleted: EventEmitter<Todo>;

  todoCompletedHandler(todo: Todo) {
    this.todoCompleted.emit(todo);
  }
}

上記のコードは、todoCompletedと呼ばれるカスタムDOMイベントをディスパッチします。

Event(opts: EventOptions)デコレータは、オプションでオプションオブジェクトを受け入れて、ディスパッチされたイベントの動作を形成します。 オプションとデフォルトについては、以下で説明します。

export interface EventOptions {
  /**
   * デフォルトをオーバーライドする文字列カスタムイベント名。
   */
  eventName?: string;
  /**
   * イベントがDOMを介してバブルアップするかどうかを示すブール値。
   */
  bubbles?: boolean;

  /**
   * イベントがキャンセル可能かどうかを示すブール値。
   */
  cancelable?: boolean;

  /**
   * イベントがShadowDOMと通常のDOMの境界を越えてバブルできるかどうかを示すブール値。
   */
  composed?: boolean;
}

例:

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

...
export class TodoList {

  //「作成」、「キャンセル可能」の「todoCompleted」というイベントがバブルアップ!
  @Event({
    eventName: 'todoCompleted',
    composed: true,
    cancelable: true,
    bubbles: true,
  }) todoCompleted: EventEmitter<Todo>;

  todoCompletedHandler(todo: Todo) {
    const event = this.todoCompleted.emit(todo);
    if(!event.defaultPrevented) {
      // 防止されていない場合は、デフォルトの処理コードを実行します
    }
  }
}

Listenデコレータ

Listen()デコレータは、 @Eventsからディスパッチされたものを含むDOMイベントをリッスンするためのものです。

以下の例では、子コンポーネント TodoListEventEmitterを使用して todoCompletedイベントを発行すると仮定します。

import { Listen } from '@stencil/core';

...
export class TodoApp {

  @Listen('todoCompleted')
  todoCompletedHandler(event: CustomEvent<Todo>) {
    console.log('Received the custom todoCompleted event: ', event.detail);
  }
}

リッスンのオプション

@Listen(eventName,opts: ListenOptions)には、DOMイベントリスナーのアタッチ方法を構成するために使用できる2番目のオプションの引数が含まれています。

export interface ListenOptions {
  target?: 'body' | 'document' | 'window';
  capture?: boolean;
  passive?: boolean;
}

The available options are target, capture and passive:

使用可能なオプションは、target,capture, passiveです。

target

ハンドラーは、ホスト自体以外のイベントに登録することもできます。 targetオプションを使用して、イベントリスナーが接続されている場所を変更できます。これは、アプリケーション全体のイベントをリッスンする場合に役立ちます。

以下の例では、 windowから発行されたスクロールイベントをリッスンします。

  @Listen('scroll', { target: 'window' })
  handleScroll(ev) {
    console.log('the body was scrolled', ev);
  }

passive

デフォルトでは、Stencilはいくつかのヒューリスティックを使用して、passiveイベントリスナーをアタッチする必要があるかどうかを判断します。 passiveオプションを使用して、デフォルトの動作を変更できます。

https://developers.google.com/web/updates/2016/06/passive-event-listenersをチェックしてください -詳細については、リスナー)を参照してください。

capture

@Listenでアタッチされたイベントリスナーは、デフォルトではcaptureしません。 イベントリスナーがcaptureに設定されている場合、それはcapture phase中にイベントがディスパッチされることを意味します。 詳細についてはhttps://www.quirksmode.org/js/events_order.htmlを確認してください。

  @Listen('click', { capture: true })
  handleClick(ev) {
    console.log('click');
  }

キーボードイベント

キーボードイベントの場合、 @Listen()で標準の keydownイベントを使用し、event.keyCodeまたは event.whichを使用してキーコードを取得するか、event.keyを使用しての文字列表現を取得できます。

@Listen('keydown')
handleKeyDown(ev: KeyboardEvent){
  if (ev.key === 'ArrowDown'){
    console.log('down arrow pressed')
  }
}

イベントキー文字列の詳細についてはw3c specを参照してください.

JSXでイベントを使用する

Stencilでコンパイルされたアプリケーションまたはコンポーネント内で、リスナーをJSXのイベントに直接バインドすることもできます。 これは、 onClickなどの通常のDOMイベントと非常によく似ています。

上からTodoListコンポーネントを使用してみましょう

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

...
export class TodoList {

  @Event() todoCompleted: EventEmitter<Todo>;

  todoCompletedHandler(todo: Todo) {
    this.todoCompleted.emit(todo);
  }
}

これで、次の構文を使用して、JSXのコンポーネントでこのイベントを直接聞くことができます。

<todo-list onTodoCompleted={ev => this.someMethod(ev)} />

非JSX要素からのイベントをリッスンする

<todo-list></todo-list>
<script>
  const todoListElement = document.querySelector('todo-list');
  todoListElement.addEventListener('todoCompleted', event => { /* your listener */ })
</script>
BackNext
Contributors