Alpine.js ディレクティブ&マジックプロパティ
はじめに
Alpine.jsは、軽量でシンプルなJavaScriptフレームワークであり、HTMLにインラインで記述されたJavaScriptを使用して要素に動的な動きをつけることができます。
大規模なプロジェクトや複雑な状態管理が必要な場合は、Vue.jsやReactを検討することが多いですが、小規模なプロジェクトやSPA的なUIの構築にはAlpine.jsをおすすめします。
Alpine.jsの特徴
Alpine.jsは、HTML内でデータとUIを簡潔に結びつけ、データの変更に応じてUIが自動的に更新されるリアクティブデータバインディングを提供しています。
また、要素の表示や非表示、追加、削除などのトランジションとアニメーションをサポートする組み込みの機能があります。
CDNを読み込むだけでプロジェクトに組み込めるのでフロントの構築がスムーズに行えます。
Alpine.jsを導入する
html<head>
タグ内に追加します。
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
パッケージマネジャーからのインストールも可能です。
ディレクティブ(Directives)
HTMLにインラインでJavaScriptを埋め込むことで、特定の要素に対して機能を追加できるディレクティブを提供します。例えば、x-data
ディレクティブはデータを要素にバインドし、x-show
ディレクティブは要素の表示/非表示を切り替えるために使用されます。Alpineは18個のディレクティブを提供しています。
ディレクティブ | 説明 |
---|---|
x-data |
コンポーネントにデータをバインドするディレクティブ。 |
x-init |
コンポーネントの初期化時に実行されるJavaScriptコードを指定するディレクティブ。 |
x-show |
要素の表示/非表示を切り替えるディレクティブ。 |
x-bind |
要素の属性やプロパティにデータをバインドするディレクティブ。 |
x-on |
イベントハンドリングを設定するディレクティブ。 |
x-text |
テキストコンテンツを設定するディレクティブ。 |
x-html |
HTMLコンテンツを設定するディレクティブ。 |
x-model |
フォーム要素の値を双方向データバインドするディレクティブ。 |
x-modelable |
モデル可能な要素に自動的にx-model を追加するディレクティブ。 |
x-for |
リストの反復処理を行うディレクティブ。 |
x-transition |
要素のトランジションやアニメーションを設定するディレクティブ。 |
x-effect |
モデルが変更されたときに自動的に実行されるコードを設定するディレクティブ。 |
x-ignore |
要素をAlpine.jsのトラッキング対象から除外するディレクティブ。 |
x-ref |
要素に参照を設定するディレクティブ。 |
x-cloak |
コンポーネントが初期化されるまで要素を非表示にするディレクティブ。 |
x-teleport |
要素をDOMの別の場所にテレポート(移動)するディレクティブ。 |
x-if |
条件に基づいて要素の表示を切り替えるディレクティブ。 |
x-id |
要素に一意のIDを設定するディレクティブ。 |
x-data
x-dataは、HTMLの一部をAlpineコンポーネントとして定義し、そのコンポーネントが参照するためのリアクティブデータを提供します。
<div x-data="{ message: 'Hello, Alpine.js!' }" x-text="message">
</div>
x-data
ディレクティブ内にJavaScriptオブジェクトがあり、そのオブジェクトのプロパティと値がコンポーネントのデータとしてバインドされます。
このデータは、その要素の範囲内のみ有効です。
x-text
はAlpine.jsによってバインドされたデータのテキスト内容を表示します。データが変更されると、自動的にUIも更新されます。
x-show
{open: false}
は要素を非表示にする初期設定です。
x-on
は、ディスパッチされたDOMイベントに対してコードを実行するディレクティブです。ここではクリックイベントに対してopen
の状態を切り替える実行されます。
x-show
ディレクティブは要素の表示/非表示を切り替える時に使います。
x-show="open"
でopen
の状態をtrue
に設定し、要素を表示させます。
x-transition
はトランジションを追加するヘルパーです。
<div x-data="{ open: false }">
<button x-on:click="open = !open">トグル
</button>
<div x-show="open" x-transition>
<p>テキスト</p>
</div>
</div>
# どちらでも大丈夫
x-on:click="open = !open"
@click="open = !open"
x-effect
x-effect は、依存関係が変更されたときに式を再評価するのに便利なディレクティブです。どのプロパティを監視するかを指定する必要がなく、その中で使用されているすべてのプロパティを監視するウォッチャーと考えることができます。
<div x-effect="console.log(open)"></div>
トグルボタンをクリックし、console.log
の内容が動的に表示されていることを確認します。
x-bind
x-bindでは、JavaScriptの式の結果に基づいて要素にHTML属性を設定することができます。
要素の表示/非表示状態によってトグルボタンのクラスを切り替えます。
# どちらでも大丈夫
x-bind:class="open ? 'bg-indigo-400' : 'bg-slate-400'"
:class="open ? 'bg-indigo-400' : 'bg-slate-400'"
x-model
x-modelでは、入力要素の値をAlpineのデータにバインドすることができます。
<div x-data="{ message: '' }">
<input type="text" x-model="message" placeholder="検索">
<div x-text="message"></div>
</div>
x-if
x-ifは、x-showと同様にページ上の要素をトグルするために使われるが、CSSのdisplayプロパティを "none"に変更するだけではなく、適用された要素を完全に追加・削除することになります。
x-showとは異なり、x-ifはx-transitionによるトグルの遷移をサポートしていません。
<div x-data="{ open: false }">
<button x-on:click="open = !open">トグル
</button>
<template x-if="open">
<div>コンテンツ</div>
</template>
</div>
x-for
x-forディレクティブを使うと、リストを繰り返し処理してDOM要素を作成できます。
配列に基づいて色のリストを作成していきます。
<ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
<template x-for="color in colors">
<li x-text="color"></li>
</template>
</ul>
DOMにリストを作られていることを確認します。
x-ref
x-ref と $refs の組み合わせは、getElementById
やquerySelector
のようなAPIの代わりとしてDOM 要素に簡単に直接アクセスできるようになります。
<button @click="$refs.text.innerText = 'Hello 👋'">Hello</button>
<p x-ref="text"></p>
x-html
x-htmlは、要素のinnerHTML
プロパティを、与えられた式の結果に設定します。
<div x-data="{ username: '<strong>田中</strong>' }">
ユーザー名: <span x-html="username"></span>
</div>
「マジックプロパティ」(Magic Properties)
マジックプロパティは、特殊な変数です。コンポーネント内で異なる操作や情報にアクセスするために使用されます。特にイベントハンドリングや動的なクラスの切り替えなど、コンポーネント内で様々な操作を行う際に便利です。Alpineは9個のマジックプロパティを提供しています。
マジックプロパティ | 説明 |
---|---|
$el |
現在のコンポーネントに関連付けられているDOM要素への参照。 |
$refs |
コンポーネント内で特定の要素にアクセスするための参照を保持するオブジェクト。 |
$store |
コンポーネントが登録された親コンポーネント(x-data 内で使用されたコンポーネント)のデータストアへの参照。 |
$watch |
コンポーネントのデータやプロパティの変更を監視するための関数。 |
$dispatch |
イベントを上位の親コンポーネントにディスパッチするための関数。 |
$nextTick |
次のDOM更新サイクルで実行されるコールバックをスケジュールする関数。 |
$root |
コンポーネントツリーのルートである親コンポーネントへの参照。 |
$data |
コンポーネントにバインドされているデータオブジェクトへの参照。 |
$id |
コンポーネントに割り当てられた一意のID。 |
$el
$elは、現在のDOMノードを取得するために使用できるマジックプロパティです。
<div x-data>
<button
x-on:click="$el.innerHTML = 'Hello World'">
Click
</button>
</div>
$watch
$watchは、指定したデータプロパティを監視し、その値が変更されたときに特定のアクションを実行することができます。
<div x-data="{ myVar: 'Initial Value' }">
<input x-model="myVar">
<button @click="$watch('myVar', newValue => console.log(newValue))">
Watch 'myVar'
</button>
</div>
$watch
ディレクティブはmyVar
というデータプロパティを監視しています。ユーザーがinput
フィールドに値を入力すると、$watch
が呼び出され、入力値に対してconsole.log
で出力する処理を行います。
$dispatch
dispatchは、ブラウザのイベントをディスパッチするためのプロパティです。
<div x-data @notify="alert('Hello World!')">
<button @click="$dispatch('notify')">
Notify
</button>
</div>
$data
$dataは現在のAlpineのdataスコープ(x-dataで提供される)にアクセスできるプロパティです。
ほとんどの場合、式の中で直接Alpineのデータにアクセスすることができます。
例えば、x-data="{ message: 'Hello Caleb!'"}
とすると、x-text="message"
のようになります。
しかし、すべてのスコープをカプセル化した実際のオブジェクトがあると、他の関数に渡すときに便利なことがあります。
<div x-data="{ greeting: 'Hello' }">
<div x-data="{ name: 'Caleb' }">
<button @click="sayHello($data)">Say Hello</button>
</div>
</div>
<script>
function sayHello({ greeting, name }) {
alert(greeting + ' ' + name + '!')
}
</script>
まとめ
Alpine.jsのディレクティブとマジックプロパティをいくつか使ってみました。
HTMLに直接記述されるJavaScriptとディレクティブの構文を使用するだけで動的なUIを構築することができて便利です!
Discussion