【Vue.js】Vue.jsの基礎

# はじめに
Vue.jsとはjavascriptのフレームワークの１つ。
フレームワークを利用することでより効率的な開発をすることができる。

VueはHTMLとjavascriptの間でデータ連携（紐づける）を行う役割を果たし、紐づけには```ディレクティブ```というVue特有の機能を用いる。

プロジェクトにVue.jsをインストールすることでVueでの開発が可能になる。
・ scriptタグを埋め込む
・ NPMを利用してインストール
・ CLIを利用してインストール(単一ファイルコンポーネントが利用可)
などいくつかのインストール方法がある。（[公式サイトを参照](https://jp.vuejs.org/v2/guide/installation.html)）


##### フレームワークとは
フレームワークはアプリケーションの設計を手助けするため、アプリケーションの骨組みとなり基本的な機能やルールを提供するもの。


## Vueのディレクティブ
Vueには名前が```v-```から始まるディレクティブというデータバインディング（HTMLとjavascriptを紐づける）を行うための機能がある。



## Vueアプリケーションの作成
Vueアプリケーションを起動させるには```Vue関数(コンストラクタ関数)```を使って```Vueインスタンス```を生成する。
Vueインスタンスを生成するには```オプションオブジェクト```を渡す。

[コンストラクタ・インスタンス・クラスなどについてはこちら](https://qiita.com/smkhkc/items/5e3729cffab6591f34c6#%E3%82%AF%E3%83%A9%E3%82%B9)

```sample.js
// Vueインスタンスを作成し、変数vmに代入
var vm = new Vue({
  // オプションオブジェクト
})
```

※上記コードで指定されているVueクラスはフレームワーク側で定義されているクラス。
※Vueインスタンスは変数に代入しなくても使用可能。複数のVueインスタンスを使用する場合は変数に代入する。

Vueアプリケーションは```new Vue```で生成された```ルートVueインスタンス```で構成され、必要に応じてネストされたツリーや再利用可能なコンポーネントで形成される。

例えば、Todoアプリのコンポーネントツリーは次のようになる。

```
ルートインスタンス
└─ Todoリスト
   ├─ Todoアイテム
   │  ├─ Todo削除ボタン
   │  └─ Todo編集ボタン
   └─ Todoリストフッター
      ├─ Todoクリアボタン
      └─ Todoリスト統計
```


ここでいうルート（root）はツリー構造の最上位に位置する要素のこと。

##### コンポーネントとは
機能ごとに切り分けられたアプリケーションを構成する部品のようなもの。

## 基本的なオプションオブジェクトの構成
オプションには使用するデータやメソッドなどを定義していく。

```sample.js
ver vm = new Vue({
  // ① マウント（繋げる）する要素
  el: 'app',
　// ② アプリケーションで使用するデータ
  data: {
    name: 'book',
    price: 1000
  },
　// ③ 算出プロパティ
  computed: {
    halfPrice: function () {
      return this.price / 2;
    }
　},
  // ④ アプリケーションで使用するメソッド
  methods: {
    halfPrice: function() {
      return this.price / 2;
    }
  }
})
```
※インスタンス内で定義したオブジェクトにアクセスする際は```this```をつける必要がある。

### ①　el　（マウント（繋げる）する要素）
Vueインスタンスを生成した際にどのHTMLにマウントする（繋げる）かをここで指定する。
elオプションの中にはHTMLの要素であるidを指定する。
ここでマウントされたHTMLの要素がアプリケーションのルートになる。

```sample.html
<div id="app">
  <p>Hello</p>
</div>
```

```sample.js
// id appにVueインスタンスを紐付ける
var vm = new Vue ({
  el: '#app'
})
```

### ② data　（アプリケーションで使用するデータ）
アプリケーションで使用するデータをここで定義する。
データには数値・文字列・ブーリアン・配列・オブジェクトなどjavascriptで使用できるデータを定義することができる。

```sample.js
var vm = new Vue ({
  el: '#app',
  // data: { プロパティ名： 値 }
  data: {
    name: 'book',
    price: 1000
}
})
// console.log(vm.name)でnameの内容が出力
```



HTMLで表示するにはマスタッシュタグ```{{ }}```を用いる。

```sample.html
<div id="app">
  <p>{{ name }}</p>
</div>
```
### ③ computed　（算出プロパティ）
computedオプションでは何らかの処理（関数）に名前をつけてプロパティとして定義することができる。

データに処理を与えたい場合、下記コードのようにHTML内に直接式を記述することも可能だが、仕組みが複雑になればコードも肥大化しコードの中身も理解しにくくなる。

```sample.html
<div id="app">
// dataオプションで定義したpriceを半分の値にして返し表示
  <p>{{ price(function() { return price / 2 }) }}</p>
</div>
```
computedオプションを利用することで与えたい処理に名前をつけてプロパティに置き換え定義することで理解しやすいコードを記述することができる。


```sample.js
var vm = new Vue ({
  el: '#app',
  data: {
    name: 'book',
    price: 1000
},
  // computed: {
  //     プロパティ名: function () {
  //       ここに処理をかく
  //     }
  //  }
  computed: {
    // プロパティhalfPriceを定義
    halfPrice: function () {
　　　　// priceの値を半分にして返す
      return this.price / 2;
    }
　}
})
```
computedオプションで定義したプロパティはdataオプションのプロパティと同じように扱うことができ、マスタッシュタグやディレクティブの値として利用することができる。

```sample.html
<div id="app">
  <!-- 500が表示される -->
  <p>{{ halfPrice }}円</p>
</div>
```
computedは```メソッドではなくプロパティなので呼び出す際に（ ）はいらない。```

[メソッドについてはこちら](https://qiita.com/smkhkc/items/5e3729cffab6591f34c6#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%81%AF)

### ④ methods　（アプリケーションで使用するメソッド）
methodsオプションではメソッドを定義することができ、定義したメソッドはマスタッシュタグやディレクティブで呼び出すことができる。ここにメソッドをまとめることで見通しの良いコードを記述することができる。
メソッドはv-onディレクティブでよく使われる。

[v-onディレクティブについてはこちら](https://qiita.com/smkhkc/items/73be65ee8e6e80e0f44e)

```sample.js
var vm = new Vue ({
  el: '#app',
  data: {
    name: 'book',
    price: 1000
},
  // methods: {
  //  メソッド名: function() {
  //    ここに処理をかく
  //  }
  // }
  methods: {
    // メソッドhalfPriceを定義
    halfPrice: function() {
      // priceの値を半分にして返す
      return this.price / 2;
    }
  }
})
```
```sample.html
<div>
  <!-- ボタンをクリックするとhalfPrice関数が実行される -->
  <button @click="halfPrice()">半額</button>
  <!-- 500円と表示される -->
  <p>{{ price }}円</p>
</div>
```

## computedとmethodsの違い
### 書き方の違い
**computed**
プロパティなので呼び出す際に```( )は不要```。引数を使った処理ができない。

**methods**
メソッドなので呼び出す際に```( )が必要```。引数を使った処理ができる。

### 動作の違い
**computed**
紐づいているデータ（dataオプションで定義した）に変更があった場合にのみ処理が実行。
データが更新されない限り一度処理した結果はキャッシュ（保存）される。毎回処理が実行されないのでその分処理が速くなる。
データと紐づいていない場合は処理が一度しか実行されない。（データが更新されないので）

**methods**
メソッドを呼び出すたびに処理が実行される。

**↓実際に動作を確認してみる**

```sample.js
// Date.now()は時間を取得するメソッド
computed: {
  computedDate: function() {
    return Date.now();
  }
},
methods: {
  methodsDate: function() {
    return Date.now();
  }
}
```

```sample.html
<ul>
  <li>{{ computedDate }}</li>
  <li>{{ computedDate }}</li>
  <!-- ↓ 処理結果 -->
  <li>1589364083951</li>
  <li>1589364083951</li>
  
</ul>
<ul>
  <li>{{ methodsDate }}</li>
  <li>{{ methodsDate }}</li>
  <!-- ↓ 処理結果 -->
  <li>1589364083951</li>
  <li>1589364292550</li>
</ul>
```

computedは何度呼び出しても一度しか処理が実行されないので出力される値も変わらない。
methodsは呼び出された回数分処理が実行されるのでバラバラの値になる。

### 使い分け方
**computed**
・ 引数が必要ない処理の場合
・ 処理を高速化させたい場合

**methods**
・ 引数が必要な処理の場合
・ 値を常に更新したい場合