【Vue.js】Vue.jsって何だろう（値変更に関わるscript編（data()・methods・computed・watch編））

## 1.はじめに。
今回は、Vue解説第三弾でVue.jsの基本的な操作のうちscriptの部分に記述する部分をいくつかまとめていきます。

## 2.基本的な書き方
Vueコンポーネントに関する説明を[第一弾](https://knowledge.is-tech.co.jp/knowledge/open.knowledge/view/512)の方に追記しました。

### 概要
``` javascript
<template>
  <!-- HTMLを書く場所：画面に表示する内容 -->
</template>

<script>
// 今回はこちらの中に書くことをまとめていきます。
export default {
  // JavaScriptを書く場所：動きやデータの処理を書く
};
</script>

<style>
/* CSSを書く場所：見た目のデザインを設定 */
</style>
```

今回は下記の概念についてまとめていきます。

| 項目 | 説明 |
| ---- | ---- |
| data() | この部品（コンポーネント）が持ってるデータ（数字や文字） |
| methods | この部品にどんな操作を加えられるか（ボタンを押すと何が起きるか） |
| computed | 部品の中のデータから自動的に計算される値 |
| watch | 部品の中のデータが変わった瞬間の動き |



## 3.解説
### ①data()  
data()とは、Vueコンポーネント内で使う<b>データの「初期状態（初期値）」を定義する場所</b>です。  
たとえば、カウントの数字やフォームの入力値など、画面に表示したり処理に使ったりする変化するデータはここに書きます。  

<b>  ＜基本的な書き方＞ </b> 
``` javascript
// data()の中に「カウント」用の変数（count）を用意している
data() {
  return {
    count: 0
  };
}
```

<b> ＜テストコード＞ </b>
``` javascript
<template>
  <div>
    <h2>カウント：{{ count }}</h2>
    <!-- ボタンをクリックするとcountが1増える -->
    <button @click="count++">1増やす</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  }
};
</script>
```

最初に表示されるのは、data内にあるcountの変数の値を見るため、「カウント：0」で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/37397a30-dba4-4bef-9d06-21452bbaab61.png)


ボタンをクリックすると count++ によりcountの値が増えていくため、「カウント：1」「カウント：2」…と変化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/82be42e2-e3c4-40e4-bad5-48336e30c239.png)


### ②methods
methodsとは、Vueコンポーネントでイベントに応じて実行したい処理（関数）を書く場所です。
ボタンを押したとき、データを加工したいときなどに使います。

<b>  ＜基本的な書き方＞ </b>   
``` javascript
methods: {
  関数名() {
    // 実行したい処理を書く
  }
}
```

<b>  ＜テストコード＞</b> 
``` javascript
<template>
  <div>
    <h2>カウント：{{ count }}</h2>
    <!-- ボタンをクリックでaddCountメソッドが実行される -->
    <button @click="addCount">1増やす</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    addCount() {
      this.count++;
    }
  }
};
</script>
```

最初に表示されるのは、data内にあるcountの変数の値を見るため、「カウント：0」で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/37397a30-dba4-4bef-9d06-21452bbaab61.png)


ボタンをクリックすると addCount() が呼ばれ、countの値が増える処理が実行されるため、「カウント：1」「カウント：2」…と増加します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/82be42e2-e3c4-40e4-bad5-48336e30c239.png)

### ③computed
computedとは、Vueで使う<b> 「計算された値」を定義する場所</b> です。
dataの値を元にして、自動的に計算してくれる（処理結果を出してくれる）便利なプロパティです。

<b>  ＜基本的な書き方＞ </b> 
``` javascript
computed: {
  新しいプロパティ名() {
    return 計算式;
  }
}
``` 

<b>  🔍methodとの違い </b> 
methodとの違いは「<b> 人が何もしなくてもdataの値の変更を検知して、自動的に処理結果を出してくれる </b> 」という点です。

たとえば、以下のようなケースを考えてみましょう。
- 名前の「姓」と「名」がある（firstName と lastName）
- この2つを合体させて「フルネーム」にしたい（fullName）
これを画面で表示するとします。

たしかに、下記のように methods で合体させてもできますが…

``` javascript
methods: {
  fullName() {
    return this.firstName + ' ' + this.lastName;
  }
}
``` 
これだと、毎回呼び出さないと更新されないため、手間がかかりますし、毎回firstNameとlastNameデータを読み込んで処理を行う必要があります。
そこで、出てくるのがcomputedです。

<b>  ＜テストコード＞ </b> 
``` javascript
<template>
  <div>
    <h2>firstName：{{ firstName }} </h2>
    <h2>lastName：{{ lastName }}</h2>
    <h3>フルネーム（computed）：{{ fullName }}</h3>
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: "山田",
      lastName: "太郎"
    };
  },
  computed: {
    fullName() {
      return this.firstName + " " + this.lastName;
    }
  }
};
</script>
``` 

初期表示では firstName と lastName を組み合わせた「フルネーム」が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/1f288b2b-95c0-4ec0-80ff-6ae8a5672267.png)

firstName または lastName を変更すれば、何もしなくても自動で fullName が更新されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/b0ea8541-a80a-47b3-b890-ec1c05369416.png)

### ④watch
watchとは、Vueの特定のdataやcomputedの値が変化したときに処理を実行する機能です。
フォームの値が変わったときに何か処理をしたい場合などに使います。

<b>＜基本的な書き方＞ </b>
``` javascript
watch: {
  監視したい変数名(newVal, oldVal) {
    // 値が変わった時に実行する処理
  }
}
```

<b> 🔍computedとの違い </b>
computedとの違いは<b>値そのものを更新するか、値の更新に基づき別の処理を実行（API呼び出し、ログ出力、他の変数の更新など）するか</b> です。

``` javascript
<template>
  <div>
    <h2>watch と computed の違い</h2>

    <input v-model="num" type="number" />

    <p>元の値: {{ num }}</p>
    <p>computed 値（numの2倍）: {{ doubleComputed }}</p>
    <p>watch 値（numの2倍、watchでセット）: {{ doubleWatched }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 1,
      doubleWatched: 0
    };
  },
  computed: {
    doubleComputed() {
      // numの2倍を計算して返すだけ
      return this.num * 2;
    }
  },
  watch: {
    num(newVal) {
      // numの更新に合わせてdoubleWatchedの値を更新する
      this.doubleWatched = newVal * 2;
    }
  }
};
</script>
``` 
computedの場合はnumの値を2倍して返すだけですが、watchの場合はnumの更新に合わせて、doubleWatchedの変数の値を2倍に更新する処理を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/0c54c6b2-f965-4614-a088-438bff37a0d8.png)



<b> ＜テストコード＞ </b>
``` javascript
<template>
  <div>
    <input v-model="keyword" placeholder="文字を入力してください" />
    <p>入力内容：{{ keyword }}</p>
    <p>ログ：{{ log }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      keyword: "",
      log: ""
    };
  },
  watch: {
    keyword(newVal, oldVal) {
      this.log = `入力が変わりました：「${oldVal}」→「${newVal}」`;
    }
  }
};
</script>
``` 

keyword に文字を入力するたびに watch が発火し、変更内容を log に記録します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/7ce939fd-f2da-4ae6-bab2-da0e84d2a5ce.png)


たとえば「abc」と入力すれば、ログには「入力が変わりました：「ab」→「abc」」のように変化が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/c14fa085-ab5d-4f9d-932b-ef2b9aa0e0d5.png)

## 4.さいごに
今回はdata()・methods・computed・watchを紹介しました。
次回もscriptタグ内に書くことをまとめていきたいと思います。