Alpine.jsを始めよう！

# はじめに

みなさま、Alpine.jsをご存知でしょうか？
まあ、ものすごく簡単に言うと **かんたんなVue.js** です。
ただでさえJSフレームワークの中では比較的簡単目なVue.jsですが、さらにかんたんです。
どんぐらいかんたんかというと **jQueryと同じかそれ以上** ってレベルです。
しゅごい！
今回はこれを紹介していこうと思います。

https://alpinejs.dev/

# JSフレームワークとは

**SPAとかJSでなんかすごいことやりたいときに入れるやつ** 、くらいの雑な認識で大丈夫です。
いわゆる3大フレームワークと言われているのがお互い影響し合いつつ、競い合っている感じです。
概ねデータバインディング（JS内の変数の値をそのまま出したり、formから書き込んだり）がしたいときに使われることが多いかと思います。

* Angular
    * おそらく一番初めに出たJSフレームワーク
    * Google製で、Google内で燃えに燃えている案件を鎮火させる過程で生まれたリアル銀の弾丸
    * ver1の頃は「AngularJS」だったが、2以降ほぼ別物になったので「JS」が名前から外れた
* React
    * もともとFacebook製
    * 近年はNextJSのvercelかReactRouterV7~(Remix)のShopifyがリードしてる感じがある
    * ~~プログラマライクな作りなおかげか~~素直にJSなので、おそらく最も人気がある
    * ReactHookが出て以降、関数型プログラミングっぽくなったおかげかで急に簡単になった
    * ふだんJSを書かない人には死ぬほど敷居が高い
* Vue.js
    * GoogleでAngularを使っていたエヴェン・ヨーによって開発された
    * 感覚的にはAngularとReactのいいとこ取りって感じ
    * 特にVue3以降のCompletisionAPIは死ぬほどReactHookの影響を受けてる
    * .vueファイルにhtmlもjsもcssもまとめて書いちゃう

# Vue.jsと違うところ、同じところ

v2の[日本語版ドキュメント](https://github.com/alpinejs/alpine/blob/v2.8.2/README.ja.md)でも白状されていますが、

> このツールのシンタックスは、ほぼ完全に Vue（それと、Angular による拡張）から借用しています。

ということで、結構シンタックスが似ています。
普段Vue.jsを使っている、あるいは挫折してしまったという人には朗報な気がします。

## 違うところ

### マスタッシュ記法 `{{ }}` でデータバインディングをしない

Vue.jsでは

```vuejs:hoge.vue
<template>
  <div>
    <p>{{ hoge }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {hoge: 'ほげ'};
  }
}
</script>
```

みたいに書くと

```
ほげ
```

って表示されます。　`script` の `data` のところで返している `hoge` を `template` の　`{{ hoge }}` のところに当てはめています。
これがいわゆるマスタッシュ記法なんですが、これがAlpine.jsだとできません。

ちなみにAlpine.jsで同じことやると

```php:hoge.blade.php
<div x-data="{hoge: 'ほげ'}">
  <p x-text="hoge"></p>
</div>
```

だけでいいのです。すごくないですか？

### ディレクティブのprefixが違う

上の例でもチラチラ出てますが、 `x-data` とか `x-text` ってところですね。
Vue.jsに `v-data` はないのですが、 `v-text` はありますよね。
そう、Vue.jsで `v-` にしていたところが `x-` になっています。
Vue.js脳の人はそのままxにしていただければいいってことですね。
なんでXなのかは知りません。エェーックス！！

### .vueファイルを作らなくていい

Vue.jsでも.vueファイル作ることが必須ではないのですが、作らずにコンポーネントを作ろうとすると大きな困難に立ち向かうことになるので、だいたい作ると思います。
Alpine.jsはhtmlソースに直接ガンガン書けるので大体のケースでは外部ファイルでわざわざJS書く必要すらありません。

## 同じところ

### シンタックスシュガーがほぼそのまま使える

まあ、とくに `on` と `bind` のところですね。
こいつらは `@` と `:` でいけます。おかげさまでVue.js書いてる感が出て楽しいです。


# タブインターフェースを作ってみよう！

Alpine.jsをつかってよくあるタブインターフェースを作ってみましょう!
Alpine.jsは今流行りの `tailwindcss` とセットで語られることが多いので、それも使ってみましょう。

## 土台のHTMLをつくる

[tailwindcssのドキュメント](https://tailwindcss.com/docs/installation)に `HTML starter template` とかちょうど良さそうなのがあるので、これを引っ張って、そこにtailwindcssとAlpine.jsをCDNから引っ張ってくるコードを足してみました。

```html:index.html
<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
  <script defer src="https://unpkg.com/alpinejs@3.3.4/dist/cdn.min.js"></script>
  <title>Alpine tab sample</title>
</head>
<body>

</body>
</html>
```

次に [tailwindcomponents](https://tailwindcomponents.com/) というサイトに良さげなタブの作例があるのでこちらを参考にさせてもらいます。今回はこちらを使用させていただきました。
https://tailwindcomponents.com/component/simple-tab

これらを使って桃太郎と浦島太郎を切り替えるタブを作ってみました。
htmlだけだとこんな感じです。

```html:index.html
<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <script defer src="https://unpkg.com/alpinejs@3.3.4/dist/cdn.min.js"></script>
  <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
  <title>Alpine tab sample</title>
</head>
<body>
    <div class="p-8">
        <div style='border-bottom: 2px solid #eaeaea'>
            <ul class='flex cursor-pointer'>
              <li class='py-2 px-6 bg-white rounded-t-lg'>桃太郎</li>
              <li class='py-2 px-6 bg-white rounded-t-lg text-gray-500 bg-gray-200'>うらしまたろう</li>
            </ul>
        </div>
        <div>
          むかし、むかし、あるところに、おじいさんとおばあさんがありました。まいにち、おじいさんは山へしば刈かりに、おばあさんは川へ洗濯せんたくに行きました。
          　ある日、おばあさんが、川のそばで、せっせと洗濯せんたくをしていますと、川上かわかみから、大きな桃ももが一つ、
          「ドンブラコッコ、スッコッコ。
          ドンブラコッコ、スッコッコ。」
          　と流ながれて来きました。
        </div>
        <div>
          むかし、むかし、あるところに浦島太郎という心やさしい漁師が住んでいました。
          ある日のこと、浜辺を歩いていると一匹の亀が子供達にいじめられているのを見ました。
          「これこれ、かめをいじめたらかわいそうだよ。はなしておやり」
          そう言って浦島太郎は子供たちから亀を助けてやりました。
        </div>
    </div>
</body>
</html>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57811/9b297075-30ec-537b-97da-602f180489b6.png)

現状話が混ざってしまってますね。ここにAlpine.jsのロジックを入れていきましょう。

## Alpine.jsの仕掛けをいれる

まずは `x-data` ディレクティブを入れます。
これは一番てっぺんのdivに入れてあげます。
`x-data` は **とっておきたいデータを入れておく場所** です。
この辺に入れます

```php
<body>
    <div class="p-8" x-data="{open: 1}">
```

`x-data` の値のところはまんまjsのobjectですね。

次にイベントハンドラを入れていきましょう。
タブのところですね。

```php
        <div style='border-bottom: 2px solid #eaeaea'>
            <ul class='flex cursor-pointer'>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 1">桃太郎</li>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 2">うらしまたろう</li>
            </ul>
        </div>
```

`@click` ってところがイベントハンドラです。clickって言っているくらいなので **ここをクリックしたら** ってところです。
値のところはどんな動作をさせるか、なんですが、ここでは `x-data` に入れている `open` の値を変えているよーっていう動作を入れています。

これでタブをクリックすれば内容が切り替わるようになったのですが、タブの色が切り替わらないので、切り替わるロジックを入れてやります。

```php
        <div style='border-bottom: 2px solid #eaeaea'>
            <ul class='flex cursor-pointer'>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 1"
              :class="{'text-gray-500 bg-gray-200': open !== 1}">桃太郎</li>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 2"
              :class="{'text-gray-500 bg-gray-200': open !== 2}">うらしまたろう</li>
            </ul>
        </div>
```

`:class` ってところが **ロジックで適用するクラスを切り替えているところ** になります。
値のobjectのvalueは判定式になっていて、そこが `true` のときにkeyに書いてあるクラスが適用されます。

## できあがり

最終的なソースはこんな感じになります。

```php:index.php
<!doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <script defer src="https://unpkg.com/alpinejs@3.3.4/dist/cdn.min.js"></script>
  <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
  <title>Alpine tab sample</title>
</head>
<body>
    <div class="p-8" x-data="{open: 1}">
        <div style='border-bottom: 2px solid #eaeaea'>
            <ul class='flex cursor-pointer'>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 1"
              :class="{'text-gray-500 bg-gray-200': open !== 1}">桃太郎</li>
              <li class='py-2 px-6 bg-white rounded-t-lg' @click="open = 2"
              :class="{'text-gray-500 bg-gray-200': open !== 2}">うらしまたろう</li>
            </ul>
        </div>
        <div x-show="open === 1">
          むかし、むかし、あるところに、おじいさんとおばあさんがありました。まいにち、おじいさんは山へしば刈かりに、おばあさんは川へ洗濯せんたくに行きました。
          　ある日、おばあさんが、川のそばで、せっせと洗濯せんたくをしていますと、川上かわかみから、大きな桃ももが一つ、
          「ドンブラコッコ、スッコッコ。
          ドンブラコッコ、スッコッコ。」
          　と流ながれて来きました。
        </div>
        <div x-show="open === 2">
          むかし、むかし、あるところに浦島太郎という心やさしい漁師が住んでいました。
          ある日のこと、浜辺を歩いていると一匹の亀が子供達にいじめられているのを見ました。
          「これこれ、かめをいじめたらかわいそうだよ。はなしておやり」
          そう言って浦島太郎は子供たちから亀を助けてやりました。
        </div>
    </div>
</body>
</html>
```
桃太郎時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57811/6aeb79c0-1613-41a1-807d-a7d857a39b6e.png)
うらしまたろう時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57811/faf0be0b-6ca6-9b94-6c53-262edecc9089.png)

# まとめ

以上、Alpine.jsのしょうかいでした！
こんな恐ろしく簡単に、サクッととんでもないことできちゃうの、熱くないですか?