今回はAlpine.jsのx-data
やx-on
のようなディレクティブの基本的な使い方について書いていきたいと思います。

目次
Alpine.jsのディレクティブ
Alpine.jsでは2020年8月の時点で14のディレクティブが利用できます。
- x-data
- x-init
- x-show
- x-bind
- x-on
- x-model
- x-text
- x-html
- x-ref
- x-if
- x-for
- x-transition
- x-spread
- x-cloak
その1:x-data
おそらくAlpine.jsでもっとも基本的なディレクティブです。
オブジェクトを使って、コンポーネントのスコープを初期化することができるほか、例2のようにスコープの外で定義した関数を使って初期化することもできます。
構造
<div x-data="[JSON data object]">...</div>
例1
まずはインラインでステートを初期化してみます。
x-dataで複数のステートを初期化したい場合には、次のようにカンマ区切りで追加することができます。
<div x-data="{name: 'Alpine.js', language: 'JavaScript'}"><p x-text="name"></p><p x-text="language || '準備中'"></p></div>
例2
今度はスコープの外で定義した関数を使って初期化してみます。
<div x-data="panel()"><button@click="handleClick"x-text="!isShow ? '展開する' : '折りたたむ'"></button><p x-show="isShow">あのイーハトーヴォの すきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。</p></div><script>function panel() {return {isShow: false,handleClick() {return (this.isShow = !this.isShow);},};}</script>
その2:x-init
x-init
ではDOMが初期化される直前のタイミングで処理を実行することができます。
構造
<div x-data="..." x-init="[式]"></div>
例
上でもDOMが初期化される直前でx-init
が実行されると書いたように、そのままではx-initが実行されるタイミングではDOMが出来上がっていません。
ためしに下のコードを実行すると、コンソールには「DOM初期化前の値」と表示されます。
<divx-data="{name: 'DOM初期化後の値'}"x-init="console.log($refs.nameInput.value)"><inputtype="text"x-ref="nameInput"value="DOM初期化前の値"/></div>
もし、inputタグのvalueを取得したいときのように、DOMが出来上がっていることを前提にしたいときには、x-init
の中でコールバック関数を使えば(() =>
)、DOMが初期化された後で処理を実行することができます。
また、次のようにx-init
の中でコールバック関数を使ってみると、コンソールには「DOM初期化後の値」と表示されます。
※ 上のコードとは、x-initの中でコールバック関数を使っている以外は同じです。
<divx-data="{name: 'DOM初期化後の値'}"x-init="() => console.log($refs.nameInput.value)"><inputtype="text"x-ref="nameInput"value="DOM初期化前の値"/></div>
その3:x-show
x-show
では要素の表示/非表示を切り替えることができます。
x-showの中がtrue
になると要素にインラインでdisplay: none
が追加され、false
になるとdisplay: none
が取り除かれます。
※ もしDOMから要素を完全に消してしまいたい場合には、x-if
を使います。
構造
<div x-show="[式]"></div>
例
下のコードではx-show
がfalseになるので文字は表示されませんが、
<div x-data="{isShow: false}"><p x-show="isShow">表示されない文字</p></div>
次のコードではx-show
の式がtrueになり、文字が表示されます。
<div x-data="{isShow: true}"><p x-show="isShow">表示される文字</p></div>
下の例では開発者ツールを使って、isShow
の値をtrue/falseで切り替えています。
その4:x-bind
x-bind
を使うと、(type属性やclass属性などの)HTML要素の属性を動的に変更することができます。
※ x-bindでは親から子へ一方通行のデータのやり取りになりますが、親と子で双方向のやり取りしたい場合には、x-model
を使います。
構造
<input x-bind:[属性]="[式]">
x-bindでは:[属性]=[式]
のようにx-bindのキーワードを省略して書くこともできます。
<input x-bind:type="..."><input :type="..."><div x-bind:class="..."></div><div :class="..."></div>
例
下のコードではisDisabled
がtrueになるとdisabled="disabled"
やdisabledClass
というクラス名が追加されます。
<form x-data="{isDisabled : false}"><inputtype="text":disabled="isDisabled":class="{'disabledClass' : isDisabled}"/></form>
その5:x-on
x-on
ではクリックやマウスオーバーなどのイベントを監視することができます。
構造
<button x-on:[event]="[expression]"></button>
x-onについても@[イベント名]="[式]"
のように、キーワードを省略して書くことができます。
<button x-on:click="..."></button><button @click="..."></button><div x-on:mouseenter="..."></div><div @mouseenter="..."></div>
例
下のコードはボタンをクリックすると+1/-1するカウンターになりますが、@click
でクリックしたときの処理を指定しています。
<div x-data="{count: 0}"><div><button @click="count++">+1</button><button @click="count--">-1</button><button @click="count = 0">リセット</button></div><p>Total:<strong x-text="count"></strong></p></div>
その6:x-model
上で書いたx-bind
は親から子への一方向のデータのやり取りをしていましたが、x-model
を使うことで親と子の双方向でデータをやり取りすることができます。
構造
<input type="text" x-model="[data item]">
例
<div x-data="{name: ''}"><input type="text" x-model="name" /><p>Hello <span x-text="name"></span></p></div>
その7:x-text
要素のテキストを更新することができます。
構造
<span x-text="[expression]"></span>
例
x-text
はinnerHTML
と同じように動くらしく、下のコードの「表示されない文字」というテキストは「山田太郎」に上書きされます。
<div x-data="{name: '山田太郎'}"><p x-text="name">表示されない文字</p></div>
また、x-textで表示したいステートが設定されてない場合のフォールバックとして、次のように||
を使うこともできます。
<div x-data="{name: '山田太郎'}"><p x-text="name || '準備中'"></p></div>
その8:x-html
x-htmlではinnerHTML
と同じように、要素のHTMLを上書きすることができます。
※ x-textではテキストを上書きしましたが、x-htmlではHTML自体を上書きします。
構造
<span x-html="[expression]"></span>
その9:x-ref
構造
<div x-ref="[ref name]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>
例
<div x-data="{name: ''}"><input type="text" x-ref="nameInput" x-model="name" /><p x-text="$refs.nameInput.value"></p></div>
その10:x-if
構造
<template x-if="[expression]"><div>Some Element</div></template>