本文へジャンプ

【デモ付き】HTMLに溶け込むJSフレームワーク『Alpine.js』の魅力

Posted by HAY

暑さが一段と厳しくなってまいりましたが、皆さまいかがお過ごしでしょうか。
こんな日は冷えっ冷えのぶっかけうどんを食べたいですね、香川出身マークアップエンジニアHAYです。
今回は最近使い始めたJSフレームワークAlpine.jsについて紹介したいと思います。

Alpine.jsとは?気軽に試せる2つの魅力

Alpine.jsは、「ちょっとした動き」をHTMLに加えたいときに適した軽量なJavaScriptフレームワークです。
特に次の点がナイスなポイントです。

  1. 圧倒的な手軽さ
    ViteやWebpackといった開発環境は一切不要です。HTMLにCDN経由でファイルを読み込むか、ダウンロードしたファイルをリンクさせるだけですぐに使い始めることができます。「コマンドラインの真っ黒な画面はちょっと苦手...」という方でも、心配ご無用です。
  2. 学習コストの低さ
    必要なのは、15個のHTML属性(ディレクティブ)と、いくつかのプロパティ・メソッドだけ。これだけで、ちょっとしたUIの動きを簡単に実装できます。

Alpine.jsの基本:ディレクティブ

Alpine.jsでは、「ディレクティブ」と呼ばれる専用のHTML属性を使って、さまざまな動きを加えます。
HTMLに「x-」から始まる属性を加えるだけで、機能が組み込めるのが特徴です。

ディレクティブ 説明
x-data コンポーネントごとにデータを定義
x-bind HTMLの属性にデータ等を結びつける
x-on イベントの監視(クリックなど)
x-text テキストコンテンツの設定
x-html 内部HTMLの設定
x-model データとフォーム入力の双方向同期
x-show 要素の表示・非表示切り替え
x-transition アニメーションの追加
x-for 繰り返し処理
x-if 条件による要素の追加・削除
x-init 初期化時に一度だけ実行
x-effect データ変更時に処理を実行
x-ref 要素への参照
x-cloak 初期化完了まで非表示(ちらつき防止)
x-ignore Alpineによる初期化を無効化

【デモ】Alpine.js 活用例

これらのディレクティブを実際にどう使うのか、具体的なデモを見ていきましょう。
※ スタイルにはTailwind CSSを使っていますが、Alpine.js自体とは切り離して考えていただいて大丈夫です。

例1:スムーズなページ内スクロール(x-data, x-on)

リンクをクリックすると、該当セクションまでスムーズにスクロールする機能です。JavaScriptで書くと少し面倒な処理も、Alpine.jsならHTMLにちょっと書き足すだけで済みます。

1. x-data属性で関数を定義


<div x-data="{
    scrollTo(id) {
      const el = document.querySelector(id);
      if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
    }">

x-data は、Alpine.jsのコンポーネントを宣言し、その中で利用できるデータや関数を定義する場所です。ここではscrollTo(id)という関数を定義しています。
この関数は、引数としてID(例:'#section1')を受け取り、そのIDを持つ要素をページ内から探し出して、scrollIntoView()で画面の先頭まで滑らかにスクロールさせます。

2. x-on属性でクリックイベントを監視


<a href="#section1" x-on:click.prevent="scrollTo('#section1')"> ... </a>

x-on属性はイベントを監視するディレクティブで、x-on:clickでクリックイベントを監視します(なお、x-on:eventNameは@eventNameと書き換えることも可能です)。
aタグに付けられた @click.prevent は、「クリックされた時」の動作を指示しています。
.preventは、aタグが本来持っている「指定された場所に一瞬でジャンプする」という動きをキャンセル(prevent)しています。
="scrollTo('#section1')" の部分で、先ほどx-dataで定義したscrollTo関数を呼び出し、引数としてスクロールさせたいセクションのIDを渡しています。
この組み合わせだけで、シンプルなスクロール機能が実現できます。

例2:チェックボックスとボタンの連動(x-model, x-bind)

「同意する」にチェックを入れたら送信ボタンが押せるようになる、よくあるフォーム機能も簡単に作れます。

1. x-dataで変数を定義


<div x-data="{ agreed: false }" ...>

agreedという名前の変数を作成し、その初期値をfalseに設定しています。

2. x-modelで変数とcheckboxの状態を同期する(双方向データバインディング)


<input 
    x-model="agreed"
    type="checkbox" 
    ...>

x-modelは、フォームの入力要素(true/false)とx-dataで定義した変数agreedを双方向で結びつけます。これにより、チェックボックスの状態(チェックあり/なし)と、Alpine.jsが管理している変数agreedを自動的に同期させます。
初期状態ではagreedにはfalseが入っていますが、ユーザーがcheckboxにチェックを入れると、agreedの値が自動的にtrueに変わります。

3. x-bindで属性の値を動的に変更


<button x-bind:disabled="!agreed">

x-bind:は、HTMLの属性(ここではdisabled属性)に動的な値を設定するためのディレクティブです(なお、x-bind:attributeNameは「x-bind」を略して:attributeNameと書くこともできます)。
x-bind:disabled="true"となるとdisabled属性が有効になります。ここではdisabled="!agreed"なので、「agreed変数がfalseの時にdisabled属性を有効にする」という意味です。つまり、チェックボックスがチェックされるとagreedがtrueになりボタンの無効化が解除されます。

例3:段階的なコンテンツ表示とプログレスバー(x-show, x-text, x-cloak, x-transition)

「次へ」を押すたびに、セクションが順番に表示されていくUIです。表示/非表示やボタンの制御を、shown という1つの変数だけで管理できるのがポイントです。

1. x-dataの変数と@clickで基本の仕組みを作る


<div x-data="{ shown: 1 }" ...>

このshown変数に入れる数値によって、表示する要素を変化させていきます。


<button @click="if (shown < 4) shown++" >

ボタンをクリックする度にshownの値を1ずつ増やします。上限はセッション数の4です。

2. x-showとx-transitionでセクションの表示制御


<section x-show="shown >= 1" x-transition x-cloak ...>

各セクションにx-showを付与し、shownの値に基づいて表示・非表示を切り替えます。例えばshownが2の時は、shown >= 1 と shown >= 2 の条件がtrueになるため、セクション1と2が表示されます。
x-transitionはx-showと組み合わせることで、セクションが表示される際に滑らかなアニメーション効果を加えます。
x-transitionのデフォルトはフェードアウトおよびスケールを150ミリ秒のtransitionで行います。durationやプロパティを変更する場合はx-transition.opacity.duration.500msと後ろに追加していきます。
さらに、x-cloakを付与することで「ちらつき」を防止します。x-cloakはAlpine.jsの準備が整うまで要素を非表示にし、ページの読み込み時に一瞬すべてのセクションが見えてしまう現象を防ぎます。
動作させるには


[x-cloak] { display: none !important; }

をCSSに追加します。

3. x-text、x-bindでプログレスバーとボタンを更新


<span x-text="shown"></span>

x-textは値をテキストとして表示します。shown変数が増加すると、x-text内のテキスト(数値)も増加して表示されます。


<div x-bind:style="`width: ${(shown / 4) * 100}%`" ...>

shownの数値に合わせてwidthの幅を変えています。
【補足】ここではstyle属性を直接書き換えていますが、x-bind:classを使えばTailwind CSSのクラスを動的に付け替えることも可能です。ただし、Tailwind CSSでw-[25%]のような任意値を使う場合、ビルド時にクラスが生成されていないと適用されない可能性があるため、style属性でインラインで書く方が安全だと思います。

4. x-bindで属性の値を変更、x-showで表示・非表示を切り替え


<button x-bind:disabled="shown === 4">
      <span x-show="shown < 4">次のセクションを表示</span>
      <span x-show="shown === 4">全てのセクションを表示しました</span>
</button>

x-bindによって、shown変数が4になると同時にボタンを無効化(disabled)します。 ボタン内のテキストも、shown変数が4になると「全てのセクションを表示しました」に切り替わります。

まとめ:Alpine.jsのよいところ

Alpine.jsは、HTMLの中にそっと機能を足していく感覚で、UIのちょっとした動きを実装できるツールです。

  1. x-data でデータや機能を定義し、
  2. x-on や x-model でユーザーの操作をデータに反映させ、
  3. x-bind や x-show 、 x-text でデータの状態をHTMLの見た目に反映させる。

この基本的な流れを覚えるだけで、多くのUIをHTML上ですっきりと宣言的に記述できるようになります。
「そこまで重い仕組みはいらないけど、もう少し便利にしたいな」という場面で、気軽に試せる選択肢だと感じました。
ご興味があれば、ぜひ触ってみてください。

Alpine.js公式サイト

Recent Entries
MD EVENT REPORT
What's Hot?