Mithrilによるシングルページアプリケーション開発 🚀 コンポーネント編
こんにちは。
manebi開発クラ部の中の人、フロントエンド担当のKです。
前回に引き続きMithrilによるシングルページアプリケーション開発の記事になります。
コンポーネントの挙動をカスタマイズする
コンポーネントを作成する中で、コンポーネントが作成されたとき、削除されたときといった、タイミングによる挙動を制御をしたいケースがあります。
代表例としては、データ表示のコンポーネントにおいて、「コンポーネントが作成されたときにデータ取得APIを呼ぶ」といったケースです。
これらはコンポーネントにライフサイクルメソッドを実装することで実現可能です。
oninitメソッド
ライフサイクルには様々なタイミングがありますが、まずは使用頻度が高いoninitを説明します。
oninitは「on initialize」の略で、コンポーネントが初期化されたときに呼ばれます。
前回作成したカウンターコンポーネントにoninitメソッドを実装し、コンソールにメッセージを表示するように変更します。
まずはカウンターコンポーネントをたくさんを呼んでいるmain.jsを元に戻します。
import m from 'mithril'
import Counter from './components/Counter'
class Home {
view () {
return m('main', [
m('h1', 'Mithril SPA'),
m(Counter)
])
}
}
const element = document.getElementById('app')
m.mount(element, Home)
次にcomponents/Counter.jsを以下のように変更します。
import m from 'mithril'
export default class Counter {
count = 0
oninit () {
console.log('Counterが初期化されました。')
}
view () {
const countUp = () => {
this.count += 1
}
return m('div', [
m('h2', 'カウンター'),
m('h3', this.count),
m('button', { onclick: countUp }, 'カウントアップ')
])
}
}
ブラウザで右クリック→検証をクリックし開発者ツールを開いてください。開発者ツールのコンソールタブに「Counterが初期化されました。」と表示されているはずです。
oninitメソッドは初期化時以外は呼ばれないので、カウントアップを押下して状態を変更しても、コンソールには追加で表示されないことも確認しておきましょう。
コンポーネントに任意の値を渡す
Counterコンポーネントはcountを状態として持っていますが、初期値を外部から設定するケースを考えてみます。
Mithrilのコンポーネントはライフサイクルメソッドとviewメソッドの引数にVirtual Node(以後vnodeと呼称)オブジェクトを受け取ります。vnodeオブジェクトに関してここでは深く触れませんが、attrs(attributesの略)というプロパティが定義されており、attrsプロパティ経由で外部から渡された値を取得できます。
components/Counter.jsを以下のように変更します。
import m from 'mithril'
export default class Counter {
count
oninit (vnode) {
// attrsにinitialCountが定義されていればその値を、定義されていなければ0を設定。
this.count = vnode.attrs.initialCount ?? 0
}
view () {
const countUp = () => {
this.count += 1
}
return m('div', [
m('h2', 'カウンター'),
m('h3', this.count),
m('button', { onclick: countUp }, 'カウントアップ')
])
}
}
この状態で再度ブラウザにアクセスしても、何も表示が変わっていないはずです。なぜならこのコンポーネントを呼んでいるmain.jsの方で値を設定していないので、初期値である0が表示されているからですね。
main.jsを変更し、カウンターコンポーネントへinitialCountを渡してみます。
import m from 'mithril'
import Counter from './components/Counter'
class Home {
view () {
return m('main', [
m('h1', 'Mithril SPA'),
m(Counter, { initialCount: 10 })
])
}
}
const element = document.getElementById('app')
m.mount(element, Home)
ブラウザを確認すると初期値として10が表示されているはずです。
余力があればmain.jsで様々なinitialCountと共にCounterコンポーネントを呼び出してみると良いでしょう。
それぞれ別の初期値を持ちながら、独立して動作する様子が確認できます。
まとめ
今回はコンポーネントの基本を解説してみました。
次回はもう少しだけMithrilの核心にせまり、「なぜカウントアップボタンを押すとcountの状態が画面に反映されるか」について解説します。
例によってゆるーく連載していきますので、気長にお待ち下さい🙇♂️