はじめに
Vuexを使用して実装しているとき、
「mapGetters
やmapState
はcomputed内に書き、mapActions
やmapMutations
はmethods内に書く」ということを深く理解せずに書いてしまっていました。
その結果、mapActions
を使用したいとき、どっちに書くのか明確な根拠を持って実装することができませんでした。
その要因として、以下の2点が理解できていないと気づいたので、アウトプットします。
- computedとmethodsの違いを明確に理解できていない
- VuexのActionsの役割を明確に理解できていない
computedとmethodsの違い
computed
は、Vueコンポーネントのデータに基づいて計算された値を提供する「プロパティ」で、methods
はVueコンポーネント内で定義される「関数」です。
大きな違いは、キャッシュの有無です。
以下にそれぞれの役割と特徴の違いを説明します。
キャッシュとは、一度計算した結果や取得したデータを一時的に保存しておき、次回以降の処理を高速化する仕組みのこと
computed(キャッシュあり)
役割:データの変化に応じて計算された値を提供し、その値をキャッシュする
computed は、その計算に使用されるデータ(依存関係)を自動的に追跡します。
これには、data、props、他のcomputedプロパティなどが含まれます。
依存するデータが変わらない限り、その計算結果をキャッシュし、再計算を行いません。
逆に言うと、依存するデータが変更されると自動的に再計算され、Vueのリアクティブシステムに基づき、UIが更新されます。
Vue のリアクティブシステムは、データの変更を自動的に検知し、必要な箇所の UI を更新する仕組みです。
data や computed の依存関係を追跡し、変更があった場合のみ再レンダリングを行うため、無駄な処理を最小限に抑えられます。
methods(キャッシュなし)
役割:ユーザーの操作やイベントに応じて処理を実行する
methodsはキャッシュされないため、呼び出されるたびに実行されます。
そのため、非同期処理や、DOM操作やAPI通信などの副作用を伴う処理に適しています。
methodsは Vue のリアクティブシステムとは独立して動作するため、computedとは異なり、依存するデータが変更されても自動的に再計算されることはありません。
そのため、「あるデータに基づいて新しい値を計算する」だけでなく、イベントの処理、データの取得・更新、その他の動的な操作に利用されます。
computedとmethodsの関係
具体的なコードを参考にして、computedとmethodsの違いと関係を理解します。
以下の例では、totalPrice
はitems
に依存しています。
したがって、items
が変更されない限り、totalPrice
を参照しても「合計金額を計算中...」は表示されません。
(computedは依存するデータが変わらない限り、その計算結果をキャッシュし、再計算を行わないから!)
しかし、addItem
メソッドでitems
が変更されると、次にtotalPrice
が参照されたときに再計算が行われ、「合計金額を計算中...」が表示されます。
これがcomputedとmethodsの関係です。
<template>
<div>
<p>合計金額: {{ totalPrice }}</p>
<button @click="addItem">商品を追加</button>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ price: 100, quantity: 2 },
{ price: 200, quantity: 1 }
]
};
},
computed: {
totalPrice() {
console.log("合計金額を計算中...");
return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
},
methods: {
addItem() {
this.items.push({ price: 150, quantity: 1 });
}
}
};
</script>
mapActionsをなぜmethodsに書くのか
computedとmethodsの違いを理解したところで、はじめに触れた「mapActions
をなぜmethodsに書くのか」を考えます。
まず、mapActionsの役割について理解します。
mapActions
はVuexストアの actions をVueコンポーネントのメソッドとして使えるようにするためのものです。
Vuexの actions は、APIの呼び出しや非同期処理など、副作用を伴う処理を実行するために使用されます。
そのため、computed に actions を入れると、リアクティブなデータの変更時に意図せず実行される可能性があるため、methods に書くのが適切です。
mapState / mapGettersについて
ここでは詳しく触れませんが、Vuexのstateはリアクティブ(変更を検知しUIを更新する)なデータであり、gettersはリアクティブなstateに依存する計算値であることから、mapState や mapGetters は computed に書くのが適切です。
computed に書くことで、Vueのリアクティブシステムと連携可能になり、キャッシュされることでパフォーマンスが向上します。
詳しくは以下を参照してください。
最後に
今回は、mapActions
どこに書くんだっけ?からはじまった疑問でしたが、この1つの疑問を解消するために理解するべきことが複数ありました。
疑問と向き合ってはじめて、自分が理解できてない点を明確にすることができました。
理解していない点がどんどん見つかるときは心が折れそうになりますが、理解する対象を見つけられた!とポジティブに捉えてひとつずつ丁寧に理解していきたいです。
最後までお読みいただきありがとうございました!
参考