はじめに
Vue.jsを触り始めた時data
やmethods
の使い方はわかりやすかったのですが、computed
の用途はよくわからなかったので、同じような方の役に立てればと思い記事を書きました。
こちらの記事はVue.js初心者向けの内容になっております。
結論
まず結論ですが、computed
は以下のような場合に使うと良いと思います。
- 定数を定義したい
- 計算した結果を返すような処理を書きたい
それでは詳細な説明に入っていきます。
目次
1.computeの特徴
2.computedの使用例
3.methodsとの比較
4.おわりに
5.参考
1. computeの特徴
- 返り値が必要
- 「リアクティブな値を参照していない場合」再実行されることはない
- 「リアクティブな値を参照している場合」参照している値が更新されたときのみ再実行される
- setterを使用しない場合、読み取りしかできない
- setterを使用しない場合引数を取れない
※リアクティブな値とは変更が検知されるような値です(data
プロパティに定義した値など)
このような特徴から「返り値のある処理」、「値の変更を検知して再実行したい処理」などに使用できます。
2. computedの使用例
次に使用例をいくつか書いていきます。
2.1 定数を定義したい
1つ目は定数を定義したい時です。
computed
にリアクティブでない値を返すように定義すれば変更できない値になり定数のように扱えます。
▼定数のように扱う例です
<template>
<div style="margin: 40px">
computedが返す値A:{{ computedValueA }}
</div>
</template>
<script>
export default {
computed: {
computedValueA() {
return 'computedValueA' // 返り値を直接書く
}
}
}
</script>
返り値を直接computed
に書いてしまえば変更できない値になるので定数として扱うことができます。
data
プロパティなどで定義した値はリアクティブになりますのでcomputed
で返しても定数のようには扱えません。
2.2 計算した結果を返すような処理を書きたい
2つ目ですが、こちらがメインの使いどころになると思います。
配列をフィルタリングして返したり、判定結果を返したり様々な場面で使用します。
計算して結果を返すようなものであれば基本的にcomputed
で書くと良いと思います。
2.2.1 配列をフィルタリングして返す
配列に入った数字から偶数のものだけをフィルタリングして表示しています。
<template>
<div style="margin: 40px">
元の状態:{{ numList }}<br />
フィルタリングした状態:{{ filtereEven }}
</div>
</template>
<script>
export default {
data: () => ({
numList: [1,2,3,4,5,6,7,8,9,10]
}),
computed: {
filtereEven() {
return this.numList.filter((num) => num % 2 === 0)
}
}
};
</script>
バックエンドから受け取った配列データをフィルタリングするなど、よくある使い方です。
2.2.2 判定結果返す
判定処理を書きたい場合にもよく使います。
以下のような処理をcomputed
で書きました。
1)奇数か偶数か判定する処理(isEvenNum
)
2)1)の判定によって表示が切り替わる処理(oddOrEven
)
<template>
<div style="margin: 40px">
<div>{{ oddOrEven }}</div>
<button @click="incrementNum()">numに1を足す</button>
</div>
</template>
<script>
export default {
data: () => ({
num: 1
}),
computed: {
isEvenNum() {
return this.num % 2 === 0
},
oddOrEven() {
return this.isEvenNum ? 'numは偶数です。' : 'numは奇数です。'
}
},
methods: {
incrementNum() {
this.num = this.num + 1
}
}
};
</script>
<style scoped>
button {
background: #eee;
border-radius: 3px;
position: relative;
max-width: 280px;
padding: 10px 25px;
color: #313131;
transition: 0.3s ease-in-out;
font-weight: 500;
}
</style>
画面読み込み時の状態です。
ボタンを押すと表示が切り替わります。
3. methodsとの比較
実は具体例として出したような処理であればmethods
でも全く同じことができます。
しかしcomputed
とmethods
では再実行される条件として以下のような違いがあります。
computed:参照する値が変更された時のみ再実行される
methods:画面が再描画されるたびに再実行される
methods
は画面が再描画されるたびに再実行されてしまうため余計な実行が増えてしまいます。
文章だけだとわかりにくいと思うので実際に例を見ていきましょう。
<template>
<div style="margin: 40px">
computedNum:{{ computedNum }}<br />
methodsNum:{{ methodsNum() }}<br />
numB:{{ numB }}<br />
<button @click="addOneNumA()">NumAに1を足す</button>
<button @click="addOneNumB()">NumBに1を足す</button>
</div>
</template>
<script>
export default {
data: () => ({
numA: 1,
numB: 1
}),
computed: {
computedNum() {
console.log('computed')
return this.numA
}
},
methods: {
methodsNum() {
console.log('methods')
return this.numA
},
addOneNumA() {
this.numA = this.numA + 1
},
addOneNumB() {
this.numB = this.numB + 1
}
}
};
</script>
<style scoped>
button {
background: #eee;
border-radius: 3px;
position: relative;
max-width: 280px;
padding: 10px 25px;
color: #313131;
transition: 0.3s ease-in-out;
font-weight: 500;
}
</style>
NumA
はcomputed
とmethods
が参照しています。
NumB
はどちらにも参照されていません。
NumA
、NumB
を変更した際にどういった挙動をするのか確認します。
3.1 画面を読み込み時
まずは画面を読み込んだ際の挙動ですが、どちらも実行されています。
3.2 「NumA」に変更があった場合
「NumAに1を足す」ボタンを押してNumA
の値が変更されました。
computed
、methods
共に実行されています。
3.3 「NumB」に変更があった場合
「NumBに1を足す」ボタンを押してNumB
の値が変更されました。
methods
のみ実行されています。
これはNumB
の値が変更され再描画されたためです。
computed
はNumA
に変更がないため再実行されません。
3.4 「methodsとの比較」まとめ
methods
を使用すると余計に再実行されてしまいますので、「計算結果を返す処理」はcomputed
で行いましょう。
4. おわりに
computed
は使用頻度は高いのでぜひマスターしていただければと思います。
記事を見ていただきありがとうございました。
5. 参考