デコレータ
デコレータは、クラスの動作を宣言的に注釈付けし、変更するために使用できる関数です。
Litは、要素の登録、リアクティブプロパティとクエリプロパティの定義、イベントハンドラメソッドへのイベントオプションの追加など、宣言的なAPIを有効にするオプションのデコレータセットを提供します。
たとえば、@customElement
デコレータと@property()
デコレータを使用すると、カスタム要素を登録し、リアクティブプロパティをコンパクトで宣言的な方法で定義できます。
@customElement('my-element')
export class MyElement extends LitElement {
@property()
greeting = 'Welcome';
}
Litは、JavaScriptデコレータの提案の2つの異なるバージョンをサポートしています。 _実験的デコレータ_ と呼ぶTypeScriptでサポートされている初期バージョンと、_標準デコレータ_ と呼ぶ新しい最終バージョンです。
2つの提案の使用方法には、いくつかの小さな違いがあります(標準デコレータでは、多くの場合、accessor
キーワードが必要です)。 現時点では本番環境での使用を推奨しているため、コードサンプルは実験的デコレータ用に記述されています。
詳細については、デコレータのバージョンを参照してください。
組み込みデコレータ
「組み込みデコレータ」へのパーマリンクデコレータ | 概要 | 詳細情報 |
---|---|---|
@customElement | カスタム要素を定義します。 | 定義 |
@eventOptions | イベントリスナーオプションを追加します。 | イベント |
@property | パブリックプロパティを定義します。 | プロパティ |
@state | プライベート状態プロパティを定義します | プロパティ |
@query | コンポーネントテンプレート内の要素を返すプロパティを定義します。 | シャドウDOM |
@queryAll | コンポーネントテンプレート内の要素のリストを返すプロパティを定義します。 | シャドウDOM |
@queryAsync | コンポーネントテンプレート内の要素に解決されるpromiseを返すプロパティを定義します。 | シャドウDOM |
@queryAssignedElements | 特定のslotに割り当てられた子要素を返すプロパティを定義します。 | シャドウDOM |
@queryAssignedNodes | 特定のslotに割り当てられた子ノードを返すプロパティを定義します。 | シャドウDOM |
デコレータのインポート
「デコレータのインポート」へのパーマリンクlit/decorators.js
モジュールを介してすべてのLitデコレータをインポートできます
import {customElement, property, eventOptions, query} from 'lit/decorators.js';
コンポーネントを実行するために必要なコードの量を減らすために、デコレータをコンポーネントコードに個別にインポートできます。 すべてのデコレータは、lit/decorators/<decorator-name>.js
で使用できます。 例えば、
import {customElement} from 'lit/decorators/custom-element.js';
import {eventOptions} from 'lit/decorators/event-options.js';
デコレータの有効化
「デコレータの有効化」へのパーマリンクデコレータを使用するには、TypeScriptまたはBabelなどのコンパイラでコードをビルドする必要があります。
将来的にデコレータがブラウザでネイティブにサポートされるようになれば、これは不要になります
TypeScriptでのデコレータの使用
「TypeScriptでのデコレータの使用」へのパーマリンクTypeScriptは、実験的デコレータと標準デコレータの両方をサポートしています。 最適なコンパイラ出力のために、TypeScript開発者は今のところ実験的デコレータを使用することをお勧めします。 プロジェクトで標準デコレータを使用する必要がある場合、または"useDefineForClassFields": true
を設定する必要がある場合は、標準デコレータへの移行までスキップしてください。
実験的デコレータを使用するには、experimentalDecorators
コンパイラオプションを有効にする必要があります。
また、useDefineForClassFields
設定がfalse
であることを確認する必要があります。 これは、target
がES2022
以上に設定されている場合にのみ必要ですが、これを明示的にfalse
に設定することをお勧めします。 これは、プロパティを宣言するときにクラスフィールドの問題を回避するために必要です。
// tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
}
}
emitDecoratorMetadata
の有効化は必須ではなく、推奨されません。
TypeScript実験的デコレータの標準デコレータへの移行
「TypeScript実験的デコレータの標準デコレータへの移行」へのパーマリンクLitデコレータは、TypeScriptの実験的デコレータモードで標準デコレータ構文(デコレータ付きクラスフィールドにaccessor
を使用)をサポートするように設計されています。
これにより、動作を変更せずに、デコレータされたプロパティにaccessor
キーワードを追加することから始めて、実験的デコレータから段階的に移行できます。 すべてのデコレータ付きクラスフィールドでaccessor
キーワードを使用したら、コンパイラオプションを変更して標準デコレータへの移行を完了できます。
// tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": false, // default for TypeScript 5.0 and up
"useDefineForClassFields": true, // default when "target" is "ES2022" or higher
}
}
注:accessor
キーワードはTypeScript 4.9で導入され、メタデータ付きの標準デコレータにはTypeScript≧5.2が必要です。
Babelでのデコレータの使用
「Babelでのデコレータの使用」へのパーマリンクBabelは、バージョン7.23以降、@babel/plugin-proposal-decorators
プラグインを使用して標準デコレータをサポートしています。 BabelはTypeScript実験的デコレータをサポートしていないため、デコレータされたクラスフィールドでaccessor
キーワードを使用して、標準デコレータ構文でLitデコレータを使用する必要があります。
これらのBabel設定で@babel/plugin-proposal-decorators
を追加することにより、デコレータを有効にします
// babel.config.json
{
"plugins": [
["@babel/plugin-proposal-decorators", {"version": "2023-05"}]
]
}
注:Litデコレータは、"version": "2023-05"
でのみ機能します。 以前サポートされていた"2018-09"
を含む他のバージョンはサポートされていません。
デコレータのバージョン
「デコレータのバージョン」へのパーマリンクデコレータは、ECMAScript標準に追加するためのステージ3の提案です。 BabelやTypeScriptなどのコンパイラはデコレータをサポートしていますが、ブラウザはまだ実装していません。 LitデコレータはBabelとTypeScriptで動作し、ブラウザがネイティブに実装したときにも動作します。
ステージ3とはどういう意味ですか?
これは、仕様テキストが完成し、ブラウザが実装する準備ができていることを意味します。 仕様が複数のブラウザに実装されると、最終ステージであるステージ4に移行し、ECMAScript標準に追加できます。 ステージ3の提案は、実装中に重大な問題が発見された場合にのみ変更されます。
以前のデコレータの提案
「以前のデコレータの提案」へのパーマリンクTC39の提案がステージ3に達する前は、コンパイラは以前のバージョンのデコレータ仕様を実装していました。
これらの中で最も注目すべきは、TypeScriptの_実験的デコレータ_であり、Litは開始以来サポートしており、現在使用することをお勧めしています。
Babelは、デコレータプラグインの"version"
オプションからわかるように、時間の経過とともにさまざまなバージョンの仕様をサポートしてきました。 以前は、Lit 2はBabelユーザー向けに"2018-09"
バージョンをサポートしていましたが、現在は以下で説明する_標準_"2023-05"
バージョンに置き換えられました。
標準デコレータ
「標準デコレータ」へのパーマリンク_標準デコレータ_ は、ECMAScript / JavaScriptを定義する機関であるTC39でステージ3のコンセンサスに達したデコレータのバージョンです。
標準デコレータは、TypeScriptとBabelでサポートされており、近い将来、ネイティブブラウザでもサポートされる予定です。
標準デコレータと実験的デコレータの最大の違いは、パフォーマンス上の理由から、標準デコレータはデコレータされ、置き換えられるクラスメンバー(フィールド、アクセサー、メソッド)の_種類_ を変更できず、同じ種類のメンバーのみを生成することです。
多くのLitデコレータはアクセサーを生成するため、これはデコレータをクラスフィールドではなくアクセサーに適用する必要があることを意味します。
これを便利にするために、標準デコレータ仕様では、"自動アクセサー"を宣言するためのaccessor
キーワードが追加されています。
class MyClass {
accessor foo = 42;
}
自動アクセサーは、プライベートフィールドを読み書きするゲッターとセッターのペアを作成します。 デコレータは、これらのゲッターとセッターをラップできます。
実験的デコレータでクラスフィールドで機能するLitデコレータ(@property()
、@state()
、@query()
など)は、標準デコレータではアクセサーまたは自動アクセサーに適用する必要があります。
@customElement('my-element')
export class MyElement extends LitElement {
@property()
accessor greeting = 'Welcome';
}
コンパイラの出力に関する考慮事項
「コンパイラの出力に関する考慮事項」へのパーマリンク標準デコレータのコンパイラ出力は、アクセサ、プライベートストレージ、およびデコレータAPIの一部であるその他のオブジェクトを生成する必要があるため、残念ながら大きくなってしまいます。
そのため、デコレータを使用したいユーザーは、可能な場合は、TypeScriptの実験的なデコレータを今のところ使用することをお勧めします。
Litチームは、将来、標準デコレータをよりコンパクトなコンパイラ出力にコンパイルするために、オプションのLitコンパイラにデコレータ変換を追加することを計画しています。ネイティブブラウザのサポートにより、コンパイラ変換の必要性もなくなります。