【Vue.js】computedとmethodsの違い

会社のソフトウェアがVue.jsによってリファクタリングされることになり、急に身につけなければいけないことになった。
まさか自分がVue.jsをやるなんて、先週までは考えもしてなかったんだが...

今公式ドキュメントを読み始めたところだけど、computedとmethodsの違いがよくわからなかったので、そこだけしっかり調べてみた。

computedはプロパティ

ドキュメントでcomputedの説明を見てみる。

Vue インスタンスに組み込まれる算出プロパティ (Computed property) です。

ん、プロパティ?
ここがmethodsとの違いその1。computedとmethodsって何が違うの?という問いには、「プロパティとメソッドは違うだろ」という答えを返せる。

試しに、computedとmethodsの部分だけを変えた、同じ処理を書いてみた。

computed

<div class="use-computed">
    <p><input v-model="number" type="number"></p>
    <p>Even / Odd : {{ answer }}</p>
</div>
new Vue({
  el: '.use-computed',
  data: {
    number: '0'
  },
  computed: {
    answer: function() {
        if (this.number % 2 != 0) return 'Odd';
      return 'Even';
    }
  }
});

methods

<div class="use-methods">
    <p><input v-model="number" type="number"></p>
    <p>Even / Odd : {{ answer() }}</p>
</div>
new Vue({
  el: '.use-methods',
  data: {
    number: '0'
  },
  methods: {
    answer: function() {
        if (this.number % 2 != 0) return 'Odd';
      return 'Even';
    }
  }
});

HTMLのmustache構文に注目。同じanswerでも、computedの方はプロパティなので()がない。対してmethodsの方はメソッドなのでanswer()と書く。
またcomputedはプロパティなので、getterだけでなくsetterも定義できる。

computedはキャッシュされる

2つめの違いとして、computedは依存関係にもとづきキャッシュされる。
上の例では、入力した整数をもとに偶数か奇数かを判定する処理をしているが、仮にページを更新しても前の入力値が変わらなければ、answerが呼び出されてもfunction()以下の処理は実行されず、前に算出したプロパティの値がそのまま出力される。
もちろん入力値が変われば再び処理が走るが、そうでなければ何回呼び出されても計算が発生しないので、不要に処理が遅くなることがない。
これに対して、methodsはメソッドなので、入力値が変わらなくても、呼び出されるたびに毎回処理が走る。

methodsは計算量を増やしてしまうことが多いが、あえてmethodsを使う場合もある。
ドキュメントにもあるが、例えばDateオブジェクトを使って今の日時を返したい場合、computedを使うと日時の値がキャッシュされ、いつアクセスしても同じ日時になってしまう。
このような場合はmethodsにしなければいけない。