Vuex では、「アクション」と「ミューテーション」の両方を持つロジックは何ですか?
コンポーネントが状態を変更できないというロジックは理解していますが(これはスマートに思えます)、アクションとミューテーションの両方があると、ある関数を作成して別の関数をトリガーし、状態を変更しているように見えます。
「アクション」と「ミューテーション」の違いは何ですか?それらはどのように連携するのですか?さらに、なぜ Vuex 開発者がこの方法で行うことにしたのか興味がありますか?
質問 1 : なぜ Vuejs 開発者はこのようにすることにしたのですか?
答え:
質問 2 : 「作用」と「突然変異」の違いは何ですか?
最初に公式の説明を見てみましょう:
突然変異:
Vuex ミューテーションは基本的にイベントです。各ミューテーションには名前とハンドラがあります。
import Vuex from 'vuex' const store = new Vuex.Store({ state: { count: 1 }, mutations: { INCREMENT (state) { // mutate state state.count++ } } })
アクション: アクションは、ミューテーションをディスパッチする単なる関数です。
// the simplest action function increment ({commit}) { commit('INCREMENT') } // a action with additional arguments // with ES2015 argument destructuring function incrementBy ({ dispatch }, amount) { dispatch('INCREMENT', amount) }
上記の私の説明は次のとおりです。
ミューテーションは同期ですが、アクションは非同期にすることができます。
別の言い方をすれば、操作が同期している場合はアクションは必要ありません。そうでない場合はアクションを実装します。
免責事項 - 私は vuejs を使い始めたばかりなので、これは私が設計意図を推定しただけです。
タイム マシンのデバッグでは、状態のスナップショットが使用され、アクションとミューテーションのタイムラインが表示されます。理論的にはactions
、状態セッターとゲッターの記録と並行して、ミューテーションを同期的に記述することができたはずです。しかしその後:
mutations
トランザクションで発生する可能性がありますが、アクションの競合状態とは対照的に、トランザクションを改善する必要があると言えます。非同期プログラミングは脆弱で難しいため、アクション内の匿名ミューテーションは、この種のバグをより簡単に再浮上させる可能性があります。次のトランザクション ログを名前付きミューテーションと比較します。
Action: FetchNewsStories
Mutation: SetFetchingNewsStories
Action: FetchNewsStories [continuation]
Mutation: DoneFetchingNewsStories([...])
名前付きミューテーションのないトランザクション ログの場合:
Action: FetchNewsStories
Mutation: state.isFetching = true;
Action: FetchNewsStories [continuation]
Mutation: state.isFetching = false;
Mutation: state.listOfStories = [...]
この例から、アクション内の非同期および匿名ミューテーションで複雑さが増す可能性があることを推測していただければ幸いです。
https://vuex.vuejs.org/en/mutations.html
ここで、アプリをデバッグしていて、devtool のミューテーション ログを確認しているとします。ログに記録されたミューテーションごとに、devtool は状態の「前」と「後」のスナップショットをキャプチャする必要があります。ただし、上記の例のミューテーション内の非同期コールバックはそれを不可能にします: ミューテーションがコミットされたときにコールバックはまだ呼び出されておらず、コールバックが実際にいつ呼び出されるかを devtool が知る方法はありません - コールバックで実行される状態のミューテーション基本的に追跡不可能です!