Alpine.js 入門



# 目次
ディレクティブ一覧
[1. x-data](#x-data)
[2. x-text](#x-text)
[3. x-on](#x-on)
[4. x-show](#x-show)
[5. x-if](#x-if)
[6. x-bind](#x-bind)
[7. x-init](#x-init)
マジックプロパティ一覧
[1. $el](#$el)
[2. $refs](#refs)
[3. $root](#$root)
[4. $watch](#watch)
# x-data
書き込んだ要素内でAlpine.js/オブジェクトデータが使用できるようになる。
```sample.html
<div x-data="{ hoge:'はろー、わーるど！' }">
  <p></p>
</div>
```
<p class="codepen" data-height="200" data-default-tab="html,result" data-slug-hash="VwBdGPe" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/VwBdGPe">
  Alpine.js 例2</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-text
オブジェクトデータをテキストとして表示する。
```sample.html
<div x-data="{ hoge:'はろー、わーるど！' }">
  <p x-text="hoge"></p>
</div>
```
<p class="codepen" data-height="200" data-default-tab="html,result" data-slug-hash="bGjKxBo" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/bGjKxBo">
  Alpine.js 例2</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

複数のプロパティも定義できる。
```sample.html
<div x-data="{ hoge:'はろー、わーるど！', fuga:'hello world!' }">
  <p x-text="hoge"></p>
  <p x-text="fuga"></p>
</div>
```
<p class="codepen" data-height="200" data-default-tab="html,result" data-slug-hash="rNrKrEZ" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/rNrKrEZ">
  Untitled</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-on
x-on:【イベント】="【処理/関数】" で定義した処理(関数)を実行できる。

例1　x-on:click  (要素をクリックした時)
```sample1.html
<div x-data="{ btn:'テストボタン' }">
  <button 
    x-text="btn"
    x-on:click="alert('ボタンが押されました！')"
  >  
  </button>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qByKMpd" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/qByKMpd">
  Alpine.js 例３</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>
例2　x-on:mouseenter (要素にマウスが入った時)

```sample2.html
<div x-data="{ btn:'テストボタン' }">
  <button 
    x-text="btn"
    x-on:click="alert('ボタンが押されました！')"
    x-on:mouseenter="btn = 'マウスが要素内に入りました'"        
  >
  </button>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="yLqExrr" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/yLqExrr">
  Alpine.js 例4</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

※補足　オブジェクトに関数を登録して呼び出す形でも実行可能。

例1　x-data内に記述する方法
```sample1.html
<div x-data="
  { 
  btn:'テストボタン',
  test_alert(){alert('ボタンが押されました！')},
  text_change(){this.btn = 'マウスが要素内に入りました'}
  }">
  <button 
    x-text="btn"
    x-on:click="test_alert()"
    x-on:mouseenter="text_change()"     
  >
  </button>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEjRqWE" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/ZEjRqWE">
  Alpine.js 例6</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

例2　scriptタグ内に記述する方法
```sample1.html
<div x-data="hogehoge()">
  <button 
    x-text="btn"
    x-on:click="test_alert()"
    x-on:mouseenter="text_change()"     
  >
  </button>
</div>
<script>
  hogehoge = () => {
    return { 
      btn:'テストボタン',
      test_alert(){alert('ボタンが押されました！')},
      text_change(){this.btn = 'マウスが要素内に入りました'}
    }
  }
</script>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="MWBXPJY" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/MWBXPJY">
  Alpine.js 例6</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

主なイベントは以下の通り。
・click: クリックイベント
・dblclick: ダブルクリックイベント
・input: 入力イベント
・keydown: キーを押した時のイベント
・keyup: キーを離した時のイベント
・mousedown: マウスを押した時のイベント
・mouseup: マウスを離した時のイベント
・mouseenter: マウスが要素に入った時のイベント
・mouseleave: マウスが要素から出た時のイベント
・mousemove: マウスを動かした時のイベント
・submit: フォームの送信イベント
・resize: ウインドウのリサイズイベント
・scroll: スクロールイベント
・touchstart: タッチイベント
・touchend: タッチ終了イベント
・touchmove: タッチ移動イベント

# x-show
値にture/falseを渡すことでその要素の表示/非表示を切り替える。
```sample.html
<div x-data="{
  open1 : true,
  open2 : false
}">
  <div x-show="open1">
      これは本文1です...
  </div>
  <div x-show="open2">
      これは本文2です...
  </div>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="MWBXPoY" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/MWBXPoY">
  Alpine.js 例7</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

ボタンを設置してtrue/falseを切り替える処理を行うことが可能。
```sample.html
<div x-data="{
  open1 : true,
  open2 : false
}">
  <div x-show="open1">
      これは本文1です...
  </div>
  <div x-show="open2">
      これは本文2です...
  </div>
  <button x-on:click="open2 = !open2">
    表示切替ボタン
  </button>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNrKqvM" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/rNrKqvM">
  Alpine.js 例8</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-if
x-showと似ているが、こちらはdisplay:none;による非表示ではなく存在自体を操作する。templateタグに記述して、その子要素が存在有無の切り替え対象となる。
```sample.html
<div x-data="{
  open1 : true,
  open2 : false
}">
  <template x-if="open1">
    <div>これは本文1です...</div>
  </template>
  <template x-if="open2">
    <div>これは本文2です...</div>
  </template>
  <button x-on:click="open2 = !open2">
    表示切替ボタン
  </button>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="poZKQER" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/poZKQER">
  Alpine.js 例9</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-bind
要素の属性を動的に書き換えることができる。

例1　inputタグのvalue,disabled属性の値を変更する。
```sample1.html
<div x-data="{
  message : 'やあ！',
  open : true
}">
  <input
    type="text"
    x-bind:value="message"
    x-bind:disabled="open"
  >
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOjKQjp" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/gOjKQjp">
  Alpine.js 例11</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

例2　inputタグのclass属性の値を変更する。
```sample2.html
<div x-data="{
    add_class : 'fuga'
}">
  <input
    type="text"
    value="テスト"
    class="hoge"
    x-bind:class="add_class"
  >
</div>

<!-- inputのクラスは class="hoge fuga" になる。 -->
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvxXQQz" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/wvxXQQz">
  Alpine.js 例11</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-transition
x-showと併用することでアニメーションを簡単に実装できる。
opacity(透明度)とscale(大きさ)のアニメーションがデフォルトで設定されている。
```sample.html
<div x-data="{ open : false }">
  <button x-on:click="open = !open">
    テストボタン
  </button>
  <p x-show="open" x-transition>
    これは本文です...
  </p>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOjKEvb" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/gOjKEvb">
  Alpine.js 例12</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

また.opacity/.scale等をメソッドチェーン式に設定することでそれらの設定変更が可能。
わかりづらいためアニメーションの速度を.durationを追加することで２秒に調整して比較してみる。
```sample.html
<div x-data="{ open : false }">
  <button x-on:click="open = !open">
    テストボタン
  </button>
  <p x-show="open" x-transition.opacity.duration.2000ms>
    これは透明度変更のみです...
  </p>
  <p x-show="open" x-transition.scale.duration.2000ms>
    これはサイズ変更のみです...
  </p>
  <p x-show="open" x-transition.scale.opacity.duration.2000ms>
    これは両方変更(初期設定)です...
  </p>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="Yzjvgoz" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/Yzjvgoz">
  Alpine.js 例14</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# x-model
HTML要素とjavascript変数を動的に結びつける。
```sample.html
<div x-data="{ message : '' }">
  <input type="text" x-model="message">
  <p x-text="message"></p>
</div>
```
<p class="codepen" data-height="200" data-default-tab="html,result" data-slug-hash="NWBzVqE" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/NWBzVqE">
  Alpine.js 例14</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

以下の入力要素で動作する。

・&lt;input type="text">
・&lt;textarea>
・&lt;input type="checkbox">
・&lt;input type="radio">
・&lt;select>

# x-init
対象要素が生成/初期化された時に実行させる処理を定義できる。
```sample.html
<div x-data="{open : false}">
  <button x-on:click="open=!open">
    テストボタン
  </button>
  <template  x-if="open">
    <p x-init="alert('初期化!')">
      要素が生成されました！
    </p>
   </template>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEjjzZp" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/ZEjjzZp">
  Alpine.js 例19</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>

# $el
記述した自身のDOM要素を参照する。
```sample.html
<div x-data>
  <button
    x-on:click="$el.textContent=$el.outerHTML">
    テストボタン
  </button>
</div>
```
<p class="codepen" data-height="250" data-default-tab="html,result" data-slug-hash="yLqEWjN" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/yLqEWjN">
  Alpine.js 例17</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# $refs
x-refで名前をつけたDOM要素を参照する。
```sample.html
<div x-data>
  <button
    x-on:click="$refs.hoge.textContent='ほげ'">
    テストボタン
  </button>
  <p x-ref="hoge">...</p>
</div>
```
<p class="codepen" data-height="250" data-default-tab="html,result" data-slug-hash="gOjjYKB" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/gOjjYKB">
  Alpine.js 例17</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# $root
記述した要素から参照して、一番近いx-data属性を持つ親のDOM要素を取得する。
```sample.html
<div x-data data-message="表示される！">
  <div data-message="無視される...">
    <button x-on:click="alert($root.dataset.message)">
      テストボタン
    </button>
  </div>
</div>
```
<p class="codepen" data-height="250" data-default-tab="html,result" data-slug-hash="VwBBZVx" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/VwBBZVx">
  Alpine.js 例18</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# $watch
指定した変数に変更があった際に行う処理を登録できる。
```sample.html
<div 
  x-data="{ count : 0}"
  x-init="$watch('count',(newValue,oldValue) => alert(`countが${oldValue}から${newValue}に変更されました`))"
>
  <button x-on:click="count++">テストボタン</button>
  <p x-text="count"></p>
</div>
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dyjjGKM" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/dyjjGKM">
  Alpine.js 例21</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# $dispatch

```sample.html
<div 
  x-data="{}" 
  x-on:testevent="alert($event.detail.value)"
>
    <button
      x-on:click="$dispatch('testevent', { value : 'ほげ' })"
    >
      テストボタン
    </button>
</div>
```

登録した関数を呼び出して実行する。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOjqvza" data-user="yumaRenacido" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yumaRenacido/pen/gOjqvza">
  Alpine.js 例22</a> by yumaRenacido (<a href="https://codepen.io/yumaRenacido">@yumaRenacido</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>