簡易アプリを作ってVue.jsの基本のキを理解する

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-116132394-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-116132394-1');
</script>

会社でこれからフロントエンド開発に取り組みそうな感じなのでその辺りの技術にこれから触れてみたいと思います。
フレームワークの選定に関しては様々な記事を拝見して、スモールスタートから始めたい、いずれ拡張ライブラリを利用したい、UI部品をコンポーネント化してごにょごにょ・・・みたいな会社の状況にも一致しそうなVue.jsを選択してみました。

[【JavaScript】３大フレームワーク Angular, React, Vue.jsを比べてみよう (2018年4月)](http://iwasiman.hatenablog.com/entry/2018/04/23/200000)
↑フレームワーク選定でお世話になった記事ですう。それぞれの特徴はもちろん、OSSのランキングとか客観的な視点も盛り込まれていて非常に参考になりました。

#本題
新しいことを始める時はなるべく公式が提供しているチュートリアルとかでやっていきたいタイプなので例に漏れず[Vue.jsの公式ガイド](https://jp.vuejs.org/v2/guide/)に沿ってやっていきます。
ただ、チュートリアルの項目単品だけだと実用性がピンとこないため、簡易なタスクアプリを作りながら多少は実用性を意識してやっていきます。

# 作ったもの
もはやありふれているタスクアプリです。

```index.html
<!DOCTYPE html>
<html>
    <head>
        <!-- 開発バージョン、便利なコンソールの警告が含まれています -->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <div>
                <!-- フォーム入力バインディング -->
                <input type="text" v-model="newtask" placeholder="input task">
                <!-- ユーザー入力の制御 -->
                <button v-on:click="add_task(newtask)">add</button>
                <ol>
                    <!-- ループ -->
                    <li v-for="task in tasks">
                        <input type="checkbox" v-model="task.completed">
                        <!-- 条件分岐-->
                        <span v-if="task.completed">-- Completed -></span> {{ task.name }}
                    </li>
                </ol>
            </div>
        </div>

        <script src="main.js"></script>
    </body>
</html>
```

```main.js
var app = new Vue({
   // vueのmodelの基底となる要素を指定
  el: '#app',
  // データの初期値を指定
  data: {
    newtask: '',
    tasks: [
      { name: 'Learn JavaScript', completed: false }, 
      { name: 'Learn Vue', completed: false}, 
      { name: 'Build something awesome', completed: false}, 
    ]
  },
  // ユーザーの入力イベントにバインドする関数を定義
  methods: {
    add_task: function(newtask){
      this.tasks.push({
        name: newtask, completed: false
      })
      this.newtask = '';
    },
  },
})
```

![vue.gif](https://qiita-image-store.s3.amazonaws.com/0/56388/7ebf1011-6ce7-0670-abef-12cdfd85c9e9.gif)


#Vue.jsの基本のキ

- はじめに
- 宣言的レンダリング
- 条件分岐とループ
- ユーザー入力の制御
- フォーム入力バインディング

### はじめに
vue.jsの使い方ですね。最初に読み込まれなければいけないのでheadタグ内に記述します。

```index.html
<!-- 開発バージョン、便利なコンソールの警告が含まれています -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
```

### 宣言的レンダリング
vueを使うときの定型句みたいなものですね。vueインスタンスとその基底となる要素を紐つけます。

```index.html
<div id="app">
    <div>
        <!-- フォーム入力バインディング -->
        <input type="text" v-model="newtask" placeholder="input task">
・
・
・
</div>
```

```main.js
var app = new Vue({
   // vueのmodelの基底となる要素を指定
  el: '#app',
  // データの初期値を指定
  data: {
    newtask: '',
    tasks: [
      { name: 'Learn JavaScript', completed: false }, 
      { name: 'Learn Vue', completed: false}, 
      { name: 'Build something awesome', completed: false}, 
    ]
  },
・
・
・
})
```

### 条件分岐とループ
条件分岐やループも`v-for`や`v-if`などのディレクティブという属性を利用してシンプルなコードで実装できました。
下記の例ではtasksという配列をfor in文で繰り返しタスクの一覧を表示します。またタスクのcompletedがtrueなら`-- Completed ->`という文字をタスク名の頭に入れて完了したタスクであることを簡易的に示しています。

```index.html
<!-- ループ -->
<li v-for="task in tasks">
    <input type="checkbox" v-model="task.completed">
    <!-- 条件分岐-->
    <span v-if="task.completed">-- Completed -></span> {{ task.name }}
</li>
```

### ユーザー入力の制御
要素にイベントリスナーをバインドできます。例えば、クリックしたときの挙動などです。例ではaddボタンを押下したときの挙動をjs側で`add_task()`という関数で定義しています。関数の内容はtasksに追加し、テキストボックスの値をクリアするためにnewtaskを初期化しています。

```index.html

<!-- ユーザー入力の制御 -->
<button v-on:click="add_task(newtask)">add</button>
```

```main.js
methods: {
    add_task: function(newtask){
      this.tasks.push({
        name: newtask, completed: false
      })
      this.newtask = '';
    },
  },
```

### フォーム入力バインディング
[フォーム入力バインディング](https://jp.vuejs.org/v2/guide/forms.html)はガイドの別セクションでしたが、必要な機能でしたので利用しました。`v-model`ディレクティブを利用しVueインスタスのモデルと要素を紐つけることができます。
(ちなみにチェックボックスに`v-model="task.completed"`を持たせることでtasksのComletedを表現できましたが、これでうまく動いてることを正確に説明できません。。。)

```index.html
<!-- フォーム入力バインディング -->
<input type="text" v-model="newtask" placeholder="input task">
・
・
・
<input type="checkbox" v-model="task.completed">
```
以上

### まとめ
- [Vue.jsの公式ガイド](https://jp.vuejs.org/v2/guide/) のはじめにの章で紹介されている初歩的な使い方と[フォーム入力バインディング](https://jp.vuejs.org/v2/guide/forms.html)のみでできました。
- Vueインスタンスの宣言などjavascriptソースコード(今回でいうとmain.js)はHTMLがレンダリングされた後じゃないと各要素を認識できないのでHTMLの最後の方に記述しないといけません。
- ディレクティブでソースコードをシンプルに書ける。
- なによりjs側でDOMを全く触りませんでした。データだけに注目できることで、Viewとモデルを切り離し、ソースコードの保守性も高くなるような気がしますね。
- これに加え、より高度な機能やコンポーネント化、エコシステムで機能拡張していけるということなので、もっと触ってみたいですね。 {^-^}