下記のようなクリックの回数によって、動的に表示を変えるプログラムがあるとする。
<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オブジェクトを用いて実装する方法
<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 ? '3より上' : '3より下'
}
}
})
</script>
次にmethodsを用いて同じ実装をしてみる。
<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 ? '3より上' : '3より下'
}
},
})
</script>
結論として、同じ挙動をするが、関数の呼び出すタイミングが異なる。
computedとmethodsの違い
methodsを定義し、{{ }}で呼び出した場合、画面が再描写されたタイミングで実行される。
つまり、全く異なる別の処理で、画面が再描写された際、check()関数が呼び出されてしまう。
これは、不必要で無駄な動作である。
computedで定義した場合は、定義した関数内部の値に変化があった場合に、呼び出される。
よって、他の処理に影響されない。
検証
下記の様に、フォームと出力部分を実装する。
methodsを用いて実装。
<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 ? '3より上' : '3より下'
}
},
})
</script>
methodsで実装した場合、フォームの値が変更され再描写されるたびに、コンソールにrunが出力されている。
つまり、関係のない処理にもかかわらず、checkプロパティに定義した関数が呼び出されてしまっている。
computedを用いて実装
<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 ? '3より上' : '3より下';
}
}
})
</script>
フォームの値を変更しても、runは呼び出されることはない。カウンターボタンを押した時のみ、runは出力される。