Ionic FrameworkとLitでToDoアプリを作る
さて、簡単な例だけでは味気ないので、前回のToDoアプリの見た目をIonic Frameworkで再実装する例も作ってみましょう。
まずはHTMLを用意しましょう。Ionic Frameworkの読み込み用の要素を配置していること以外は、前回のToDoアプリとほとんど変わりません(リスト2)。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>IonicとLitで作るToDoリスト</title> <!-- Ionic Frameworkを読み込む --> <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script> <script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" /> <!-- (1) Ionic Frameworkより後に自作のJavaScriptモジュールを読み込む --> <script type="module" src="./ionic-todo.js"></script> </head> <body> <!-- 自作のカスタム要素を表示する --> <ionic-todo-list></ionic-todo-list> <!-- Ioniconを読み込む --> <script type="module" src="https://cdn.jsdelivr.net/npm/ionicons/dist/ionicons/ionicons.esm.js"></script> <script nomodule src="https://cdn.jsdelivr.net/npm/ionicons/dist/ionicons/ionicons.js"></script> </body> </html>
次に、(1)で読み込んでいるJavaScriptを作成しましょう(リスト3)。
import {LitElement, html, map, css} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js'; class IonicToDoListElement extends LitElement { static properties = { tasks: { state: true, }, hideCompleted: { type: Boolean, reflect: true, }, }; static styles = css` .completed { text-decoration-line: line-through; color: #777; } :host([hideCompleted]) .completed { display: none; } `; constructor() { super(); this.tasks = [ { id: 1, label: 'カプセル化と再利用性について学ぶ', completed: true }, { id: 2, label: 'Web ComponentsのAPIを学ぶ', completed: true }, { id: 3, label: 'Litの基本的なAPIを学ぶ', completed: true }, { id: 4, label: 'Litの実践的な使い方を学ぶ', completed: true }, { id: 5, label: 'UIライブラリを使ってみる', completed: false }, ]; } render() { return html` <ion-app> <ion-header> <ion-toolbar> <ion-title>ToDoリスト</ion-title> </ion-toolbar> </ion-header> <ion-content> <!-- (1) --> <ion-list> ${map(this.tasks, (task) => { return html` <!-- (2) --> <ion-item class=${task.completed ? 'completed' : ''}> <ion-label>${task.label}</ion-label> <ion-checkbox slot="start" ?checked=${task.completed} @click=${(event) => this.setChecked(task, event)} ></ion-checkbox> </ion-item> `; })} </ion-list> <ion-item-divider></ion-item-divider> <ion-list> <ion-item> <ion-label>完了したタスクを隠す</ion-label> <ion-checkbox slot="start" ?checked=${this.hideCompleted} @ionChange=${this.setHideCompleted} ></ion-checkbox> </ion-item> </ion-list> </ion-content> </ion-app> `; } setChecked(task, event) { task.completed = event.target.checked; this.requestUpdate(); } setHideCompleted(event) { this.hideCompleted = event.target.checked; } } customElements.define('ionic-todo-list', IonicToDoListElement);
render()
の戻り値以外はほとんど前回から変更していないので、連載を追ってくださっている方から見ると、見覚えのあるものになっていると思います。リスト3のファイルを作成したら、リスト2のionic-todo.html
をブラウザで表示してみましょう。図6のような見た目になります。
今回の再実装で着目してほしいのは、(1)の<ion-list>
、(2)の<ion-item>
の2点です(図7)。
<ion-list>
はリスト全体を囲んで、項目を縦方向に並べるためのカスタム要素です。項目の並べ替えや、項目をスワイプして裏側にオプションを表示する機能などがサポートされています。<ion-item>
は項目1つ分のUIを表現するためのカスタム要素です。paddingが適切に設定されたり、内部のチェックボックスとラベルが中央揃えで横に並んでいたりと、中身を綺麗に並べる役割があります。
このように、ライブラリからカスタム要素を拝借してくるだけで、かなりアプリっぽい見た目のものを作れました。
まとめ
今回はIonic FrameworkをWeb Components仕様のUIライブラリとして使用する方法について解説しました。せっかくなので、次回はIonic Frameworkにはどんなカスタム要素があるのかを解説していきます。