はじめに
Vuexの state をアクセスする方法には2つあります。
- 直接
this.$store.state.xxxなどで直接stateにアクセスする -
Vuex.getters(以下、getters) を用いてstateにアクセスする
どちらの方法でも state にアクセスできますが、getters をどう使い分けをしたらいいのか、自分の中で理解できなかったので調べてみました。
getters について
Vuex 公式ドキュメントには次のように書かれています。
Vuex を利用するとストア内に "ゲッター" を定義することができます。それらをストアの算出プロパティと考えることができます。算出プロパティと同様に、ゲッターの結果はその依存関係に基づいて計算され、依存関係の一部が変更されたときにのみ再評価されます。
~ 中略 ~
プロパティとしてアクセスされるゲッターは Vue のリアクティブシステムの一部としてキャッシュされるという点に留意してください。
computed や watch 同様に、getters はオブジェクト指向プログラミングでよく使われる getter と同義でないことがわかりました。
state を直接参照する場合と getters を使い分けるには?
TL;DR
単にstateの値を取得するだけ(オブジェクト指向などで使われる一般的なgetter)であれば、 state を直接参照する
何らかの計算処理を行なった結果を取得するのであれば getter を使用した方が望ましい
getters は公式ドキュメントの引用のよればキャッシュ機構が備わっているため、 computed と一緒に使うと二重にキャッシングされてしまいます。
// store(vuex)
export default new Vuex({
state: {
musicList: [
{ id: 1, name: foo, category: 'pop' },
{ id: 2, name: bar, category: 'rock' }
]
}
getters: {
musicList: state => state.musicList
}
})
// component (vue)
export default {
computed: {
getMusicList() {
return this.$store.getters.musicList // コンポーネント側とVuex側で二重にキャッシングされてしまう
}
}
}
ただし、いくつかの複数のコンポーネントで stateを用いて何らかの計算処理を行い場合は、コンポーネント側で計算処理が重複して記述されるのを防ぐため、 getters を記述すべきでしょう。
// store(vuex)
export default new Vuex({
state: {
musicList: [
{ id: 1, name: foo, category: 'pop' },
{ id: 2, name: bar, category: 'rock' }
]
}
getters: {
rock: state => state.musicList.filter((music) => music.category === 'rock')
}
})
// component (vue)
export default {
computed: {
getRockMusicList() {
return this.$store.getters.rock // これはOK!
}
// computed側で記述すると、計算処理が重複してしまう
// getRockMusicList() {
// const musicList = this.$store.getters.rock
// return musicList.filter((music) => music.category === 'rock')
// }
}
まとめ
gettersにはキャッシュ機構が備わっている。-
computed(watch) と併用して利用すると二重でキャッシュしてしまうため、stateを直接参照する。 -
stateを参照して何らかの計算処理などを行い、かつ複数コンポーネントでその計算処理が利用される場合は、gettersを利用する。