Alpine.js 5分で説明するよ

はこです、こんにちわ。
今日は [Alpine.js](https://alpinejs.dev/) の話をします。


![gahag-0013866791.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/83f328e1-366e-764d-6511-f669fc440518.jpeg)

# Alpine.js 何？

Alpine(アルパイン: 英語風発音) は 『アルプスの・転じて登山用の』を意味します。

- アルペン: Alpine のドイツ語読み。スノーレジャーやアウトドアグッズとかのお店。
- アルパインブーツ・アルパインウェア: 雪山や高山に適した超軽量かつ高機能な服や靴。
    - [モンベルのアルパインクッカー](https://webshop.montbell.jp/goods/disp.php?product_id=1124690) など…。
- Alpine Linux: 超軽量Linux. Small Simple Secure が合言葉。
- Alpine.js: 超軽量なフロントエンドフレームワーク。
    - 当初は7kb(gzipped), 今は機能が増えてそれでも11kb
        - Vueの58kbよりもかなり軽い
    - 覚えることは20個のみ


Vue, React, Angular 等の SPAツールの 超シンプル版だと思って間違いないです。

Alpineを名乗るだけあって、 **軽量だけど高機能** って感じです。


合言葉は

```
 Simple.       シンプル.
 Lightweight.      軽量.
 Powerful as hell.    鬼ヤバにパワフル.
```

## ざっくり概要

- HTMLのシンタックスを使った、モダンWebにおけるjQuery(のような立ち位置のもの)
- 既存サイトからの部分的な改良も可( `<script src="alpine.js">` 入れるだけ. vueと同じ)
- 覚えることは22個だけ。




## 22個の覚えること

[公式に書いてあるよ](https://alpinejs.dev/alpine-101)

- `x-` から始まる 14個 の属性(アトリビュート) "Directives" 
- `$-` から始まる  6個 のプロパティ "Magics"
- `Alpine.data` と `Alpine.store` の 2個のメソッド

以上！！


##### 省略記法
めっちゃ使う やつだけは、省略記法(シュガーシンタックス)があります。
2個だけ！ 

- `x-on:` は `@` 
    - `@click="someMethod(...)"` で使います
- `x-bind:` は `:`
    - `<div :class="closed ? 'hidden' : ''">` のように css classをつけたり、 `<input type="text" :placeholder="'入力してください'">` のように html の属性に設定したりします。


これで覚えることはおしまい！
すくない！！

## サンプル

もうこれで完璧です！
覚えることの時間はおしまい！

サンプルコードを読んでみましょう！


#### シンプルなカウンタ
```html
<div x-data="{ count: 0 }">
    <button x-on:click="count++">カウンタが増えるボタン</button>
    <span x-text="count"></span> <!-- 数字はここに出る -->
</div>
```

<p class="codepen" data-height="268" data-theme-id="light" data-default-tab="result" data-user="kohashi" data-slug-hash="wvJNdqK" style="height: 268px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="wvJNdqK">
  <span>See the Pen <a href="https://codepen.io/kohashi/pen/wvJNdqK">
  wvJNdqK</a> by Kohashi (<a href="https://codepen.io/kohashi">@kohashi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

はい！超シンプルです。

#### ボタンをクリックしたら、開く

```html
<!-- x-dataで書いたオブジェクトは子要素からアクセス可能、ここではopen状態の値を保持するやつ -->
<div x-data="{ open: false }">
    <!-- @click は onclick の代わりだよ。クリックしたら open=true を代入する(開くよ)  -->
    <button @click="open = true" x-text="open ? '開いてるよ' : 'クリックで開くよ'"></button>

    <!-- x-show は 指定した変数や式が true なら、表示するよ -->
    <span
        x-show="open"
        @click.away="open = false"
        style="border: solid black 1px; padding: 10px;"
    >
        開いたよ。この枠の外をクリックすると、閉じるよ。
    </span>
    <!-- @click.away の .away は「ここ以外を xxしたら(clickしたら)」 の修飾子だよ。 
         「画面外をクリックしたら」でよく使うよね  -->
</div>
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="result" data-user="kohashi" data-slug-hash="eYvoVpp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="eYvoVpp">
  <span>See the Pen <a href="https://codepen.io/kohashi/pen/eYvoVpp">
  eYvoVpp</a> by Kohashi (<a href="https://codepen.io/kohashi">@kohashi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

スタイルとか当ててない機能サンプルですが、これでダイアログボックスやタブが作れますね！


#### HTMLテンプレートを使用しないカウンタ

「よりjsだけで書きたい！」ということも出来ます。

最初のカウンタのサンプルと同じですが、このように書くことも出来ますー。

```js
// DOM参照して取ってくるだけ
let button = document.querySelector('button');
let span = document.querySelector('span');

// Alpine.reactiveで、リアクティブなデータとして定義
let data = Alpine.reactive({ count: 1 });

// Alpine.effectで、リアクティブなデータが変更されると呼ばれる関数を設定します。
Alpine.effect(() => {
    span.textContent = data.count;
})

// ここはバニラなJSですねー
button.addEventListener('click', () => {
    data.count = data.count + 1
})
```

詳しくは [ドキュメント見てね](https://alpinejs.dev/advanced/reactivity)。


#### その他のサンプル

https://www.alpinetoolbox.com/

ここに色々のってるよ。

(注意: 2系のサンプルがまだ多いよ. 最新は3系だよ. でもあんま違いはないよ)



#### 通信どうすんの？

**[Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API) 使うといいよ！**

`fetch('url...')` は IE以外では使えますし、[ポリフィルもある ](https://github.com/github/fetch) ので実質全ブラウザで使えますね（暴言)。

表示する内容を fetch するサンプル

```html
<span x-text="getLabel()"></span>

<script>
async function getLabel() {
    let response = await fetch('/api/label'); // 任意のAPIのURL
    return await response.text(); // 戻り値を返す
}
</script>
```


マウスオーバーしたときに、次のページ取得するサンプル

```html
<!-- open で開くよ。最初はfalseなので閉じてる -->
<div x-data="{ open: false }">

    <!--  マウスオーバーしたときに1度だけ(@mouseenter.once) fetchして、結果の中身のhtmlをnextPageDivに代入するよ -->
    <button
        @mouseenter.once="
            fetch('/next-page.html')
                .then(response => response.text())
                .then(html => { $refs.nextPageDiv.innerHTML = html })
        "
        @click="open = true"
    >次のページへ！</button>

    <!-- クリックしたとき(open===trueのとき) 表示されるよ。 -->
    <div x-ref="nextPageDiv" x-show="open">
        <!-- fetch完了前は「ページ読込中...」、完了後は next-page.htmlの中身が表示されるよ -->
        ページ読込中...
    </div>
</div>
```

#### 自分のディレクティブ作りたい！
`Alpine.directive` でできるよ。

```html
<script>
// こういうのを定義する
Alpine.directive('to-neko', el => {
    el.textContent = el.textContent + 'にゃ！ 🐾 😺'
})
</script>

<!-- こう使う -->
<div x-to-neko>はろー</div>
<!-- はろーにゃ！ 🐾 😺  と表示される -->
```

[ドキュメント見てね](https://alpinejs.dev/advanced/extending)

## ユースケース

これは私見になるのですが、「既に構築された(大規模に作り直すことが困難な)Webサイトを部分的にインタラクティブにしたい」というケースには非常によくマッチすると思います。
以前はこのようなケースでは Vue.js が選ばれることが多かったように思いますが、Vueよりもシンプルながらよい作りのAlpineがより適してるでしょう。

逆に、「ゼロから作りたい！」というユースケースでも充分に役に立ちます。
シンプルなゆえに覚えることが少なく、サクッと作れるのは魅力です。
技術検証や最初のリリースとしては充分適しているでしょう。

反面、TypeScriptはサポート外であることや、高機能なcliは付属しないこと、htmlテンプレートのエディタのサポートの弱さや自動テストが困難な点など、大規模に多人数が関わって開発するのにはやや不足感は否めません。

しかし、関わる人が慣れてる人だけである場合や、小規模に高速に開発していくケースでは力になりそうです！


# まとめ

Alpine.js は アルパインの名の通り、無骨で最小限ですが高機能なフロントエンドフレームワークでした。

また、同様に軽量CSSフレームワークの [Tailwind CSS](https://tailwindcss.com/) との相性が良さそうです。

どちらもシンプルで覚えることが少ないため、半日もあれば充分書けるようになるのではないでしょうか。


### 参考資料

公式

https://github.com/alpinejs/alpine

公式の日本語訳
https://github.com/alpinejs/alpine/blob/2.x/README.ja.md
ちょっと更新が古いけど、そもそも覚えることが少ないから大丈夫だよ！