はじめに
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
を利用する。