242

Vuex では、「アクション」と「ミューテーション」の両方を持つロジックは何ですか?

コンポーネントが状態を変更できないというロジックは理解していますが(これはスマートに思えます)、アクションとミューテーションの両方があると、ある関数を作成して別の関数をトリガーし、状態を変更しているように見えます。

「アクション」と「ミューテーション」の違いは何ですか?それらはどのように連携するのですか?さらに、なぜ Vuex 開発者がこの方法で行うことにしたのか興味がありますか?

4

13 に答える 13

288

質問 1 : なぜ Vuejs 開発者はこのようにすることにしたのですか?

答え:

  1. アプリケーションが大きくなり、複数の開発者がこのプロジェクトに取り組んでいる場合、「状態管理」(特に「グローバル状態」) がますます複雑になることがわかります。
  2. vuex の方法 ( react.js のRedux と同様) は、状態を管理し、状態を維持し、「保存して追跡可能」にする新しいメカニズムを提供します (つまり、状態を変更するすべてのアクションは、デバッグ ツール: vue-devtoolsによって追跡できます) 。

質問 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)
}

上記の私の説明は次のとおりです。

  • 突然変異は状態を変更する唯一の方法です
  • 突然変異はビジネスロジックを気にせず、「状態」だけを気にします
  • アクションはビジネスロジック
  • アクションは一度に複数のミューテーションをコミットできます。ビジネス ロジックを実装するだけで、データの変更 (ミューテーションによって管理されます) は気にしません。
于 2016-09-03T05:55:11.287 に答える
80

ミューテーションは同期ですが、アクションは非同期にすることができます。

別の言い方をすれば、操作が同期している場合はアクションは必要ありません。そうでない場合はアクションを実装します。

于 2016-11-15T13:02:06.073 に答える
5

免責事項 - 私は 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 が知る方法はありません - コールバックで実行される状態のミューテーション基本的に追跡不可能です!

于 2016-12-19T02:23:39.150 に答える