【Vue.js】computedの記法について（methodsとの違い)

下記のようなクリックの回数によって、動的に表示を変えるプログラムがあるとする。

![e4a29d22e51f889a00acbf85335145f5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/6847bb53-5766-ce26-5263-1e05c366e607.gif)

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
  <button @click="counter">カウンター</button>
  <div>{{number >3 ? '3より上':'3より下'}}</div>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      number: 0
    },
    methods: {
      counter: function () {
        this.number += 1
      }
    }
  })
</script>
```
conputedオブジェクトを用いて実装する方法

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
  <button @click="counter">カウンター</button>
  <div>{{check}}</div>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      number: 0
    },
    methods: {
      counter: function () {
        this.number += 1
      }
    },
    computed: {
      check: function () {
        return this.number > 3 ? '３より上' : '３より下'
      }
    }
  })
</script>
```

次にmethodsを用いて同じ実装をしてみる。

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
  <button @click="counter">カウンター</button>
  <div>{{ check() }}</div>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      number: 0
    },
    methods: {
      counter: function () {
        this.number += 1
      },
      check: function () {
        return this.number > 3 ? '３より上' : '３より下'
      }
    },

  })
</script>
```
結論として、同じ挙動をするが、関数の呼び出すタイミングが異なる。

##computedとmethodsの違い
methodsを定義し、{{ }}で呼び出した場合、画面が再描写されたタイミングで実行される。
つまり、全く異なる別の処理で、画面が再描写された際、check()関数が呼び出されてしまう。
これは、不必要で無駄な動作である。

computedで定義した場合は、定義した関数内部の値に変化があった場合に、呼び出される。
よって、他の処理に影響されない。

##検証
下記の様に、フォームと出力部分を実装する。

![f9d0620f0a0e960b8c30faaa568a3cab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/c798590b-2920-c3c6-8a15-e301aab33254.gif)

### methodsを用いて実装。

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
  <button @click="counter">カウンター</button>
  <div>{{ check() }}</div>
  <p>{{test}}</p>
  <input v-model="test">
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      number: 0,
      test: "test"
    },
    methods: {
      counter: function () {
        this.number += 1
      },
      check: function () {
        console.log('run');
        return this.number > 3 ? '３より上' : '３より下'
      }
    },
  })
</script>
```
methodsで実装した場合、フォームの値が変更され再描写されるたびに、コンソールにrunが出力されている。
つまり、関係のない処理にもかかわらず、checkプロパティに定義した関数が呼び出されてしまっている。

###computedを用いて実装

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
  <button @click="counter">カウンター</button>
  <div>{{ check }}</div>
  <p>{{test}}</p>
  <input v-model="test">
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      number: 0,
      test: "test"
    },
    methods: {
      counter: function () {
        this.number += 1
      },
    },
    computed: {
      check: function () {
        console.log('run');
        return this.number > 3 ? '３より上' : '３より下';
      }
    }
  })
</script>
```
フォームの値を変更しても、runは呼び出されることはない。カウンターボタンを押した時のみ、runは出力される。