筋トレしながらわかる💪Vue.js入門

![bodybuilding-311351_640.png](https://qiita-image-store.s3.amazonaws.com/0/115251/b4f4235b-4492-e3db-0e8a-7a39be7036cd.png)

# Vue.jsとは？

Vue.jsは多機能で、少しずつ適用していくことが出来るクライアント側のJavaScriptフレームワークです。これは筋トレも同じ。筋トレも多機能（様々な鍛え方がある）で、日常にトレーニングを少しずつ組み入れていくことができます。

こんな似ているモノ同士を同時に説明し、相乗効果（？）を高めて見ようという画期的な試みがこの記事です。

# 何を説明するのか？

Vue.jsには様々な機能がありますが、コア&基本となる以下の３つを取り上げます。

- リアクティブ
- リストレンダリング
- イベントハンドリング

## リアクティブ
Vue.jsはデータとDOMが関連付けられ**リアクティブ**になっています。**これは筋肉に例えると腹直筋です**。体の中心に位置し、体を支える重要な筋肉の様にリアクティブであることはVue.jsにとってとても重要です。Vue.jsはリアクティブによって成り立ち、故に便利なのです。腹直筋が何処の筋肉かわからない？ググって、どうぞ。

簡単な例を用いて説明しましょう。以下は、単純に「プロテイン」と画面に表示する例です。


```html:index.html
<div id="app">
  {{ message }}
</div>
```

```javascript:vue.js
const app = new Vue({
  el: '#app',
  data: {
    message: 'プロテイン'
  }
})
```

```tex:結果
プロテイン
```

Vue.jsを使うにはまず、`Vue`関数でVueインスタンスを作成するところから始まります。Vue関数の引数は様々なものがありますが特に重要なものが`el`と`data`です。`el`は、Vueインスタンスがバインドする（紐づく）DOM要素を指定し、`data`はVueインスタンスのプロパティを指定します。

- `el` : VueインスタンスがバインドするDOM要素
- `data` : Vueインスタンスが持つプロパティオブジェクト

一方`html`側では、VueインスタンスにバインドされているDOM要素以下で、`{{ message }}`のように書きVueインスタンスの`message`プロパティの値を描画できます。

Vue関数の`data`によって渡されたオブジェクトは、すべてリアクティブになっています。なので、**`data`の内容を書き換えるとそれに反応してビューが再レンダリングされ、最新の値を表示してくれます。**

例えば、`message`の値をランニングに変えると次の瞬間ビューではランニングと表示されています。

```html:index.html
<div id="app">
  {{ message }}
</div>
```

```javascript:Console
app.message = 'うますぎる！'
```
```tex:結果
うますぎる！
```

ちなみに、`data`で指定するものはオブジェクトなので、複数のプロパティを指定することができます。例えばこんな感じです。


```html:index.html
<div id="app">
  <p>{{ menu1 }}</p>
  <p>{{ menu2 }}</p>
  <p>{{ menu3.name }} : {{ menu3.speed }}</p>
</div>
```

```javascript:vue.js
const app = new Vue({
  el: '#app',
  data: {
    menu1: '腹筋',
    menu2: '腕立て伏せ',
    menu3: {
      name: 'ランニング',
      speed: '8.0km/h'
    }
  }
})
```

```tex:結果
腹筋

腕立て伏せ

ランニング : 8.0km/h
```

## リストレンダリング

リストレンダリングとは名前から想像がつく様に、リストのデータをHTMLへレンダリングする機能です。つまり、**上腕二頭筋を鍛えると重いものを軽々と運べる様に、リストレンダリングは反復作業を楽に処理できます。**

皆さん会社の帰りにジムメニューを考えていると思います（ですよね？）。そうした時には以下の様なデータ構造とメニュー内容を思いつくと思います。

```js:vue.js
const app = new Vue({
  el: '#app',
  data: {
    todayMenu: [
      'アブドミナル',
      'ラットプルダウン',
      'バックエクステンション',
      'チェストプレス'
    ]
  }
})
```

`todayMenu`に文字列がリストで格納されています。それぞれをHTML出力するには以下の様に書きます。

```html:index.html
<div id="app">
  <div v-for="menu in todayMenu">
    {{ menu }}
  </div>
</div>
```

```text:結果
アブドミナル
ラットプルダウン
バックエクステンション
チェストプレス 
```

リアクティブの時とほとんど変わっていませんが、 **`v-for`という属性があります。これが、Vue.jsでのリストのレンダリング方法です。** `v-for="menu in todayMenu"`という部分でVueインスタンス内の`todayMenu`リストの一つ一つの要素を順に取り出し、`menu`という一時変数に格納しています。そして、取り出した要素分`v-for`属性が付与されたDOM要素以下を繰り返しレンダリングします。

リストの要素が単純な型でなかったとしても、Vue.jsを使えばとても簡潔な方法でレンダリングできます。例えば、それぞれのメニューに負荷を加えたいとしましょう。すると、この様になります。

```js:vue.js
const app = new Vue({
  el: '#app',
  data: {
    todayMenu: [
      {label:'アブドミナル', weight: 45},
      {label:'ラットプルダウン', weight 40},
      {label:'バックエクステンション', weight: 50},
      {label:'チェストプレス', weight: 50}
    ]
  }
})
```

```html:index.html
<div id="app">
  <div v-for="menu in todayMenu">
    {{ menu.label }}({{ menu.weight }})
  </div>
</div>
```

```text:結果
アブドミナル(45)
ラットプルダウン(40)
バックエクステンション(50)
チェストプレス(50) 
```

## イベントハンドリング

日々のトレーニングでも瞬発力が大切ですが、Vueの世界でも同様（？）にイベントの処理は大切です。Vue.jsではDOMイベントの購読とそれに紐づいたJavaScriptを発火する事は非常に簡単です。以下の例では、ボタンがクリックされた時に表示を更新する単純な例です。

```html
<div id="app">
  <button v-on:click="changeMsg">change message</button>
  <p>{{ message }}</p>
</div>
```

```javascript
const app = new Vue({
  el: '#app',
  data: {
    message: 'プロテイン'
  },
  methods: {
    changeMsg: function () {
      this.message = 'うますぎ'
    }
  }
})
```

ボタンと`プロテイン`という文字が表示され、ボタンをクリックすると`プロテイン`が`うますぎ`に変わります。

一体何が起こったのでしょうか？Vue.jsでは **タグに`v-on:DOMイベント`と記述する事でDOMイベントの購読をすることができます** 。なので上記の例では`button`タグに`v-on:click`と記述されているため、ボタンクリックのイベントを購読しています。

さらに**Vue関数に`methods`というプロパティを渡すことで関数をVueインスタンスに渡すことができます。**この例では`changeMsg`という名前で関数をVueインスタンスに登録しています。その関数を、ボタンがクリックされた時に発火するように`v-on:click="changeMsg"`と書いて指定しています。

`v-on`では、様々なDOMイベントを指定することが出来ます。例えば、マウスがボタンに被さったイベントを拾いたければ`v-on:mouseenter`のように書けます。

# おわりに

ここで紹介したことはVue.jsのほんの一部です。他にもVue.jsには様々な機能があります。

- [Vue.js公式サイト](https://jp.vuejs.org/)

様々な機能の中でも特に私が注目しているのが以下です。

- [単一ファイルコンポーネント](https://jp.vuejs.org/v2/guide/single-file-components.html):コンポーネント化（これ面白い）
- [Vuex](https://vuex.vuejs.org/ja/):状態管理
- [vue-router](https://jp.vuejs.org/v2/guide/routing.html):ルーティング

また、これらの他にも様々なサードパーティライブラリが続々登場中です。

- [Vue.js色々まとめ](https://qiita.com/SatoTakumi/items/36204b04e5743d666a26)

皆さんも是非Vue.jsと筋トレの世界に足を運んで見てください。