Vue.js 入門（第２回） - 算出プロパティ（computed）と監視（watch） -

# はじめに
Vue.jsに少し触れてみたので、その内容を「Vue.js入門」として、数回にわけて書いていこうと思います。
今回の２回目では「**算出プロパティ（computed）**」と「**監視（watch）**」を紹介します。
１回目は「[Vue.js 入門（第１回） - Vue.jsでHello World と双方向データバインディング（v-model） -](https://qiita.com/yasushi-jp/items/b5226a5379b3539da81b "Vue.js 入門（第１回） - Vue.jsでHello World と双方向データバインディング（v-model） -")」を参照してください。

※ここではVue.jsの**2.x系（2.6.14）**を使用しています。**3.x系**では書き方が異なるので注意してください。

# 1. 算出プロパティ（computed）

**算出プロパティ**とは、あるデータや別の算出プロパティから算出される新たなデータのことです。
`computed`オプションを指定することで、算出プロパティを定義することができます。
インスタンスのデータが更新されると、それに依存している算出プロパティも更新されます。

### 1.1. jsの作成

```js:js/main.js
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'yasushi',
    lastName: 'jp'
  },
    computed: {             // （１）
    getName: function() {   // （２）
      return this.firstName + ' ' + this.lastName;
    }
  }
});
```

（１）`computed`で算出プロパティを定義します。
（２）算出プロパティの名称を`getName`として、`getName`が返す値を`function`内に定義します。ここではデータ：`firstName`とデータ：`lastName`をスペースを付けて連結した値を返します。
　

### 1.2. HTMLの作成

```html:index.html
<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8">
    <title>Vue.js（computed）</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
  </head>
  <body>
    <div id="app">
      <p>Vue.jsのバージョンは {{ Vue.version }} です。</p>
      <p>firstName: <input type="text" v-model="firstName"></p> <!-- （１） -->
      <p>lastName: <input type="text" v-model="lastName"></p>   <!-- （２） -->
      <p>Name: {{ getName }}</p>  <!-- （３） -->
    </div>
    <script src="js/main.js"></script>
  </body>
</html>
```

（１）の入力値を`firstName`と紐付けます。
（２）の入力値を`lastName`と紐付けます。
（３）で`main.js`の算出プロパティで定義した`getName`を表示します。

### 1.3. 動作確認

ブラウザで`index.html`を開くと以下の通り表示されます。
`firstName`や`lastName`に入力すると、`Name`に`firstName`と`lastName`を連結した値が表示されます。
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/2c9b8750-c789-d8f1-a7e1-f317e6fa4bbd.png)

# 2. 監視（watch）

`watch`オプションを指定することで、データや算出プロパティの変更を監視することができます。
オプションのキーに変更を監視したいプロパティ名を設定すると、そのプロパティ名の値が更新された際に関数が実行されます。
実行される関数の第１引数に変更後の値、第２引数に変更前の値が渡されます。

### 2.1. jsの作成

```js:js/main.js
var vm = new Vue({
  el: '#app',
  data: {
    firstName: 'yasushi',
    lastName: 'jp',
    oldName: '',  // （１）
    newName: ''   // （２）
  },
    computed: {
    getName: function() {
      return this.firstName + ' ' + this.lastName;
    }
  },
  watch: {    // （３）
    getName: function(newVal, oldVal) {   // （４）
      this.oldName = oldVal;    // （５）
      this.newName = newVal;    // （６）
    }
  }
});
```
（１）（２）データに`oldName`と`newName`のプロパティ名を定義します。
（３）`watch`を指定します。
（４）算出プロパティの`getName`を監視します。第１次引数の`newVal`には変更後の`getName`の値が、第２引数の`oldVal`には変更前の`getName`の値が渡されます。
（５）`oldName`に変更前の値を設定します。
（６）`newName`に変更後の値を設定します。


### 2.2. HTMLの作成

```html:index.html
<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8">
    <title>Vue.js（computed）</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
  </head>
  <body>
    <div id="app">
      <p>Vue.jsのバージョンは {{ Vue.version }} です。</p>
      <p>firstName: <input type="text" v-model="firstName"></p>
      <p>lastName: <input type="text" v-model="lastName"></p>
      <p>Name: {{ getName }}</p>      <!-- （１） -->
      <p>Name(old): {{ oldName }}</p> <!-- （２） -->
      <p>Name(new): {{ newName }}</p> <!-- （３） -->
    </div>
    <script src="js/main.js"></script>
  </body>
</html>
```
（１）算出プロパティ`getName`を表示します。`getName`の値は入力項目の「firstName」と「lastName」をスペースを付けて連結した値となります。
（２）変更前の値の`oldName`を表示します。
（３）変更後の値の`newName`を表示します。

### 2.3. 動作確認
ブラウザで`index.html`を開くと以下の通り表示されます。
入力項目の「firstName」と「lastName」を変更すると、「Name」の値が変更され、変更前の「Name」（Name(old)）と変更後の「Name」（Name(new)）が表示されます。

![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/cfabae8d-f8ca-82d1-d909-98671d100034.png)

# 参考
+ [Vue.js](https://jp.vuejs.org/ "Vue.js")
+ [とほほのVue.js入門](https://www.tohoho-web.com/ex/vuejs.html "とほほのVue.js入門")

# リンク
+ [Vue.js 入門（第１回） - Vue.jsでHello World と双方向データバインディング（v-model） -](https://qiita.com/yasushi-jp/items/b5226a5379b3539da81b "Vue.js 入門（第１回） - Vue.jsでHello World と双方向データバインディング（v-model） -")
+  [Vue.js 入門（第３回） - メソッド（methods） -](https://qiita.com/yasushi-jp/items/52f4b77f2ec2a8d9c15c "Vue.js 入門（第３回） - メソッド（methods） -")
+  [Vue.js 入門（第４回【最終回】） - ToDoリストを作ってみる -](https://qiita.com/yasushi-jp/items/4416390dde26153073bd "Vue.js 入門（第４回【最終回】） - ToDoリストを作ってみる -")