Alpine.jsについて

## はじめに

こんにちは、@yuki_itoiです。
最近転職をしたのですがフルリモートワークで作業をしており、運動不足に悩まされそうな予感がしています。
案件に参加してAlpine.jsというフレームワークで書かれたソースを初めて見ることになり、勉強がてら記録に残したいと思います。

## 基本概念

Alpine.jsは、2019年12月にCaleb Porzio氏によって公開されました。
公式ドキュメント
https://alpinejs.dev/
>Alpine is a collection of 15 attributes, 6 properties, and 2 methods.

15の属性、6のプロパティ、そして2つのメソッドとのことです。
Vue.jsやReactと比較してとてもコンパクトな印象を受けました。
学習曲線も穏やかそうですね。
また、Vue.jsに似たディレクティブシステムを採用しており、`x-data`、`x-bind`、`x-on`などのディレクティブを使用してHTMLに動的な振る舞いを追加します。
Vue.jsを使うまでもないけど何かJSのフレームワークで効率よく小 ~ 中規模の開発をしたいといったニーズに合ってそうだと感じました。

## 技術を採用するとしたら

既存のプロジェクトの強化や、小規模なウェブアプリケーションへの導入が良さそうです。
CDNからスクリプトを読み込むだけで使用可能な点、HTMLの中に直接かけるので比較的プロジェクトの途中からの導入も簡単にできそうだなと感じました。

## プロパティの使い方について
よく使いそうなAlpine.jsの主要なディレクティブとその使用方法を説明します。

#### x-data
```html
<div x-data="{ count: 0 }">
  <p>カウント: <span x-text="count"></span></p>
  <button @click="count++">増やす</button>
</div>
```
変数や関数を初期化して、定義した小要素で使用することが可能になリます。
#### x-bind
```html
<div x-data="{ isRed: true }">
  <p x-bind:class="isRed ? 'text-red' : 'text-blue'">この文字の色が変わります</p>
  <button @click="isRed = !isRed">色を切り替え</button>
</div>
```
ボタンをクリックするたびにisRedの値を変えて、<span style="color:#c94c03;">classの要素を動的に変えることができる。
また、x-bindは省略できて、下記のように書くこともできます。
```html
<p :class="isRed ? 'text-red' : 'text-blue'">この文字の色が変わります</p>
```
#### x-on
```html
<div x-data="{ message: '' }">
  <input type="text" x-model="message">
  <button x-on:click="alert(message)">メッセージを表示</button>
</div>
```
x-onディレクティブは、DOM要素にイベントリスナーを追加するために使用されます。
x-onの省略形として@記号を使用できます。これは特にクリックイベントで頻繁に使われます。
```html
<button @click="alert(message)">メッセージを表示</button>
```

#### x-text
```html
<div x-data="{ name: '太郎' }">
  <p>こんにちは、<span x-text="name"></span>さん！</p>
</div>
```
x-textディレクティブは、要素のテキストコンテンツを動的に設定するために使用されます。
この例では、<span>要素のテキストコンテンツが name 変数の値（この場合は '太郎'）に設定されます。

```html
<div x-data="{ firstName: 'John', lastName: 'Doe' }">
  <p x-text="`${firstName} ${lastName}`"></p>
</div>
```
x-textには単純な変数だけでなく、JavaScript式を指定することもできます。

```html
<div x-data="{ isLoggedIn: false }">
  <p x-text="isLoggedIn ? 'ようこそ！' : 'ログインしてください'"></p>
</div>
```
三項演算子を使用して条件付きでテキストを表示することができます

#### x-model
```html
<div x-data="{ email: '' }">
  <input type="email" x-model="email">
  <p>入力されたメールアドレス: <span x-text="email"></span></p>
</div>
```
x-modelディレクティブは、フォーム要素とプロパティの間に双方向データバインディングを作成します。これにより、ユーザーの入力に応じてデータが自動的に更新され、またデータの変更が即座に表示に反映されます。
この例では、input要素の値とemailが双方向にバインドされています。
ユーザーが入力するとemailの値が更新され、その値が<span>要素にリアルタイムで表示されます。

#### x-show
```html
<div x-data="{ isVisible: false }">
  <button @click="isVisible = !isVisible">表示切替</button>
  <p x-show="isVisible">これは表示されたり隠れたりします。</p>
</div>
```
x-showディレクティブは、要素の表示/非表示を切り替えるために使用されます。
x-showの値がtrueの場合、要素が表示されます。
falseの場合、要素は非表示になります（display: noneが適用されます）。
ボタンをクリックすると、isVisibleの値が切り替わり、テキストの表示/非表示が切り替わります。

#### x-for
```html
<div x-data="{ fruits: ['りんご', 'バナナ', 'オレンジ'] }">
  <ul>
    <template x-for="fruit in fruits">
      <li x-text="fruit"></li>
    </template>
  </ul>
</div>
```
x-forディレクティブは、配列やオブジェクトに対してループを実行し、動的にDOM要素を生成します。
注意する点としては、x-forは<template>タグ内で使用する必要があります。

#### x-if
```html
<div x-data="{ isLoggedIn: false }">
  <template x-if="isLoggedIn">
    <p>ようこそ、ユーザーさん！</p>
  </template>
  <template x-if="!isLoggedIn">
    <p>ログインしてください。</p>
  </template>
</div>
```
x-ifディレクティブは、条件に基づいて要素をDOMに追加または削除します。
isLoggedInの値に応じて、異なるメッセージが表示されます。
x-ifも<template>タグ内で使用する必要があります。

## まとめ
Vue.jsやReactなどの大規模フレームワークほどの機能はありませんが、それゆえに学習コストが低く、導入が容易な印象を受けました。
大規模なシングルページアプリケーション（SPA）の開発等には向いてなさそうですが、既存のウェブサイトに動的な要素を追加したり、小規模なアプリケーションを迅速に開発したりする場合には非常に効果的なツールとなりそうです。