サンプルコンポーネントを作る
概要
詳細な説明に入る前に実際のコンポーネントがどのようになっているのか、簡単なコンポーネントを作成して雰囲気をみてみましょう。ここではボタンを押すと挨拶をするコンポーネントを作ります。このコンポーネントはタイトルの下にボタンが一つあり、そのボタンを押すと“Hello, World!”と挨拶するハローコンポーネントです。
全ソースは最後にあります。とてもシンプルなので、経験を積んだプログラマーの方なら最初に目を通しておくと、より早く理解ができるかもしれません。
以下の流れでコンポーネントを作成していきます。
- コンポーネントの名称を決める
- コンポーネントのHTMLファイルを作成する
- コンポーネントのJSファイルを作成する
- 設定を記述する
- イベントハンドラを作成する
- コンポーネントを表示するHTMLファイルを作成する
- サーバーに配置する
1. コンポーネントの名称を決める
コンポーネントを作るにあたって、まずコンポーネントに必要な様々なものの名称を決めていきます。
BitsmistJSのコンポーネントは通常、コンポーネントの動作を記述するJavascriptファイルと、画面を定義するHTMLファイルからなります。コンポーネントによっては複数のHTMLファイルを切り替えて使ったり、画面が全くないものもあります。また、動作が必要ないコンポーネントはJavascriptファイルがなくHTMLファイルのみとなります。
名称を決める必要があるのは次の3つです。
- タグ名
- クラス名
- ファイル名
タグ名
BitsmistJSではコンポーネントは全て標準技術であるWeb Componentsのカスタムエレメントを使って作成されます。それぞれのコンポーネントには独自のタグが必要となります。タグ名の付け方にはルールがあり、かならずハイフンが一つ必要です。
今回は“pad-hello”というタグにします。
クラス名
コンポーネントに動作(イベントハンドラ)が必要な場合、クラスを定義して作成する必要があります。BitsmistJSではタグ名のハイフンを取り除き、それぞれの単語の先頭を大文字にしたものをデフォルトのクラス名としています。今回の場合は“PadHello”という名前になります。
動作が必要ない場合Javascriptファイルは不要ですが、内部では自動的にタグ名を元にクラスを生成し処理しています。
ファイル名
BitsmistJSのデフォルトではタグ名に拡張子“.js”をつけたものをJavacriptのファイル名、タグ名に拡張子“.html”をつけたものをHTMLファイルのファイル名としています。デフォルトではないファイル名も使用可能ですが、シンプルにするためここではデフォルトに従います。
今回は1つのJavascriptと1つのHTMLファイルからなるコンポーネントを作るので、ファイル名をそれぞれ“pad-hello.js”、“pad-hello.html”とします。
2. コンポーネントのHTMLファイルを作成する
表示されるコンポーネントの画面のHTMLファイルを作成します。タイトルの下に、ボタンが一つある画面です。
<h1>Hello Component</h1> <button id="btn-greet">Greet</button>
ファイル名は先ほど決めた通り“pad-hello.html”です。
ファイルには今回作成する<pad-hello>タグの中身のみを記述します。このHTMLファイルが<pad-hello>タグの中に差し込まれます。
3. コンポーネントのJSファイルを作成する
コンポーネントが何らかの動作をする場合、その動作を記述したクラスを定義したJavascriptファイルが必要になります。クラスはBitmistJSのベースコンポーネントを継承する必要があります。
ベースとなるコンポーネントを継承する
BitmistJSではベースとなるコンポーネントを継承し、カスタムコンポーネントを作成していきます。現在のところBitsmistJS Coreライブラリは“Component”という名前のベースコンポーネントのみを提供しています。このComponentを継承して自身のベースコンポーネントを作成し、それを使用することも可能です。
クラスを定義する
継承元のコンポーネントはBITSMIST.v1グローバルオブジェクトの中に存在するので、実際に継承するときは以下のようになります。
class PadHello extends BITSMIST.v1.Component { }
ファイル名は“pad-hello.js”です。
さらにタグとこのクラスを紐付けます。こうすることで、ブラウザがこのタグに対しては、このクラスを使ってくれるようになります。
class PadHello extends BITSMIST.v1.Component { } customElements.define("pad-hello", PadHello);
4. 設定を記述する
次にこのコンポーネントの設定を先ほどと同じ“pad-hello.js”に記述します。設定は_getSettings()関数をオーバーライドして、設定内容のオブジェクトをリターンします。
他の記述方法もあります。
class PadHello extends BITSMIST.v1.Pad { _getSettings() { return { "settings": { "name": "PadHello" }, "events": { "btn-greet": { "handlers": { "click": "onBtnGreet_Click" } } } }; } } customElements.define("pad-hello", PadHello);
ここでは基本的な設定であるコンポーネント名を“settings”セクションに設定しています。
コンポーネント名はデフォルトではコンストラクタ名となりますが、難読化した際には失われてしまいますので、明示的に設定しておくことをお勧めします。
また、このコンポーネント内にあるボタンをクリックした時にどの関数を実行するかを指定する設定を“events”セクションに記述してあります。この記述方法の詳細については、イベントオーガナイザのリファレンスをご覧ください。
5. イベントハンドラを作成する
次に“pad-hello.js”内にイベントハンドラを作成します。このコンポーネントにはボタンが一個あり、そのボタンを押したときの動作を記述します。イベントハンドラ名は先ほどの設定に記述したとおり、“onBtnGreet_Click”としています。
class PadHello extends BITSMIST.v1.Pad { ...省略... onBtnGreet_Click(sender, e, ex) { alert("Hello, world!"); } } customElements.define("pad-hello", PadHello);
全てのイベントハンドラは同じシグニチャを持ちます。
6. コンポーネントを表示するHTMLファイルを作成する
作成したコンポーネントを表示するHTMLファイルを作成します。ファイル名は“sample.html”とします。
<html> ... 省略 <body> <pad-hello bm-autoload="/pad-hello.js"></pad-hello> </body> </html>
今回作成したコンポーネントのタグを配置しています。bm-autoloadタグの属性に、コンポーネントのJSファイルへのURLを記述します。このプロジェクトではすべてのファイルをルート直下におきます。
7. サーバーに配置する
作成した3つのファイル、sample.html、pad-hello.js、pad-hello.htmlを全てサーバー上のルート直下に配置します。
今回は分かりやすさのために全てルート直下に配置していますが、自由に配置できます。
配置が完了したら、実際にsample.htmlをブラウザで読み込み表示させます。ボタンを押すとメッセージが表示されるはずです。
完全なソース
今回作成した全ソースをまとめておきます。
- sample.html
<html> <head> <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/bitsmist/bitsmist-js_v1@0.9.9/dist/bitsmist-js_v1.min.js"></script> <title>BitsmisJS Sample</title> </head> <body> <pad-hello bm-autoload="/pad-hello.js"></pad-hello> </body> </html>
- pad-hello.html
<h1>Hello Component</h1> <button id="btn-greet">Greet</button>
- pad-hello.js
class PadHello extends BITSMIST.v1.Component { _getSettings() { return { "settings": { "name": "PadHello" }, "events": { "btn-greet": { "handlers": { "click": "onBtnGreet_Click" } } } }; } onBtnGreet_Click(sender, e, ex) { alert("Hello, world!"); } } customElements.define("pad-hello", PadHello);