computedとmethodの違いについて【Vue2】

環境

Vue:2.6.11

内容

computedはVue.jsで使用できる算出プロパティです。データの変更を感知して算出後の値をreturnする機能を持ちます。

下記のコードではcomputedを{{ "computed:" + countOverThreeComputed }}で記述し、countの値が3を超えると表示が切り替わるようにしています。

同じような機能をmethodを使っても実装することができます。

{{ "method:" + countOverThreeMethod() }}ではmethodを使ってcountOverThreeComputedと同じ動きを実現しています。

<template>
 <div>
   <button @click="increment">+1</button>
   <p>{{ count }}</p>
   <p>{{ "computed:" + countOverThreeComputed }}</p>
   <p>{{ "method:" + countOverThreeMethod() }}</p>
 </div>
</template>
 
<script>
export default {
 data() {
   return {
     count: 0
   };
 },
 computed: {
   countOverThreeComputed() {
     return this.count > 3 ? "3以上" : "3以下";
   },
 },
 methods: {
   countOverThreeMethod() {
     return this.count > 3 ? "3以上" : "3以下";
   },
   increment() {
     this.count++;
   },
 },
};
</script>
<style scoped>
</style>

初期表示 countが4を超えるとどちらも表示が切り替わる

ではcomputedとmethodでは何が違うのでしょうか?

公式リファレンスでは「算出プロパティは、リアクティブな依存関係が更新されたときにだけ再評価されます」とあります。

jp.vuejs.org

上記のコードでいうと、「countOverThreeComputed」はcountが変更されたときのみ実行されるということです。

逆に「countOverThreeMethod」はcountしか参照していないにもかかわらず、count以外の変数が変更されても実行されてしまいます。

変数「otherCount」とotherCountをインクリメントするメソッドを追加し、countOverThreeComputedとcountOverThreeMethodの中にそれぞれconsole.logを記述して動きを見てみます。

<template>
 <div>
   <button @click="increment">+1</button>
   <p>{{ "count " + count }}</p>
   <button @click="incrementOther">+1</button>
   <p>{{ "otherCount " + otherCount }}</p>
   <p>{{ "computed:" + countOverThreeComputed }}</p>
   <p>{{ "method:" + countOverThreeMethod() }}</p>
 </div>
</template>
 
<script>
export default {
 data() {
   return {
     count: 0,
     otherCount: 0,
   };
 },
 computed: {
   countOverThreeComputed() {
     console.log("computed");
     return this.count > 3 ? "3以上" : "3以下";
   },
 },
 methods: {
   countOverThreeMethod() {
     console.log("method");
     return this.count > 3 ? "3以上" : "3以下";
   },
   increment() {
     this.count++;
   },
   incrementOther() {
     this.otherCount++;
   },
 },
};
</script>
<style scoped>
</style>

otherCountが変更されると「countOverThreeComputed」は実行されませんが、「countOverThreeMethod」が実行されてしまいます。

このように、関係のない変数が変更されるたびにmethodの関数も動いてしまうため、プロジェクトの規模が大きくなった場合など、処理がとても重くなります。

まとめ

{{}}内の関数など、computedで記述すべきところをmethodで書くと上記のような問題が起こります。

クリックイベントなどで実行する関数はmethodで良いですが、{{}}内に記述して参照先を感知して動的に値を変更したい場合はcomputedの使用が推奨されています。