イベント
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イベントをリッスンするためのものです。
以下の例では、子コンポーネント TodoList
がEventEmitter
を使用して 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>
Contributors
Thanks for your interest!
We just need some basic information so we can send the guide your way.