Hookとは
HookとはLiveViewのライフサイクルに合わせてJavaScriptの処理を実行できるもの。
例えばheexに<script>
で直接JavaScriptを記述したときと、
Hookでmounted関数プロパティに処理を記述することがイコールになる。
Hookを使用するために必要になる最小限の追加ファイルは次のようになる。
なお全てassets/jsのディレクトリ内である。
ファイル or ディレクトリ | 説明 |
---|---|
hooks.js | JavaScriptをまとめるために必要 |
/hooks | JavaScriptファイルを格納する |
/hooks/*.js | JavaScriptファイル |
Hookの動作としては次のようになる
- phx-hookにHookを指定したタグを記述する。
- ページが読み込まれる際、Hookが読み込まれる
- LiveViewライフサイクルに合わせて対応する関数プロパティが実行
Hookの設定
Hooksを使用する手順は次の通り
- Hookを定義する
- HookをまとめたHooksを定義する
- app.jsに追記
Hookを生成するための準備として以下を作成する。
- hooks.js
- /hooks
Hook定義するためには、/hooksディレクトリにjsファイルを生成する。
生成したjsファイルには、Hookオブジェクトを作成する。
Hookを定義するための関数プロパティは次のようになる。
- mounted() - mount後に実行される
- updated() - hookを適用したタグが更新されたときに実行。
その他はこちらを参照する。
Hookの作成
例としてChangeColorというHookオブジェクトを作成する。
/hooks/changeColor.jsというファイルを作成する。
とりあえず作成する際は、以下のように記述する
なおHookの関数プロパティについては後述するものとする。
const ChangeColor = {
// ここに関数プロパティを記述する
}
export default ChangeColor;
つづいてhooks.jsで作成したHookをまとめる。
import ChangeColor from './hooks/changeColor'
const Hooks = {
ChangeColor: ChangeColor
}
export default Hooks
app.jsに追記してLiveViewがHookを使用できるようにする。
...
import Hooks from './hooks'
...
let liveSocket = new LiveSocket("/live", Socket,
{
params: {_csrf_token: csrfToken},
// 追記
hooks: Hooks
}
)
HTMLの処理の対象となるタグのphx-hook
にHookを指定して使用
<button id="change-id" phx-hook="ChangeColor">Change Color Button</button>
Hookの処理を定義
例として押すとidがtarget
であるタグの背景を赤色に変更する処理を定義する。
この処理はmount時にスクリプトを実行する必要があるのでmounted()
という関数プロパティに記述する。
phx-hookを指定した要素はthis.el
で参照ができる。
よって以下のようになる
const ChangeColor = {
// 追加
mounted() {
this.el.addEventListener('click', _ => {
const targetElement = document.getElementById('target');
if (targetElement) {
targetElement.style.backgroundColor = 'red';
}
})
}
}
export default ChangeColor;
実行すると色が変わる処理が実行されていることが確認できる。
結論
JavaScriptの処理を実行したり、JavaScriptのライブラリを使用する際は、Hookを使用すること。
おまけ
LiveViewからHookに値を渡す
イベントの処理に以下を実行する。
push_event(socket, "sample_event", %{name: "Taro"})
Hook側で以下を記述する。
this.handleEvent("sample_event", object => {
console.log(object.name)
})
よってpush_event(socket, "イベント", map)
によって、Hookにmapがオブジェクトに変換されて値を渡すことができる。
HookからLiveViewに値を渡す
LiveViewプロセスに対してイベントを送信するには、次のように記述する。
this.pushEvent("copied_text", {名前: 値})
this.pushEventTo(this.el, "copied_text", {名前: 値})