Vuexアクションvsミューテーション


173

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

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

「アクション」と「ミューテーション」の違いは何ですか、それらはどのように連携しますか。さらに、なぜVuex開発者がこのように行うことにしたのか不思議です。


2
「On To Actions」を参照してください。vuex.vuejs.org
Roy J

関連するディスカッション:github.com/vuejs/vuex/issues/587
chuck911

1
ストアの状態を直接変更することはできません。ストアの状態を変更する唯一の方法は、明示的に変更をコミットすることです。そのためには、変異をコミットするアクションが必要です。
Suresh Sapkota

1
声明は非常に両方として、混乱していることを@SureshSapkota mutationsactions状態を変更する方法としてvuexドキュメントでdefintedされています。ミューテーションをコミットするためのアクションは必要ありません。
グラハム、

1
名前が示すように、ミューテーションは、状態オブジェクトの変更/ミューテーションに使用されます。アクションはミューテーションに非常に似ていますが、状態を変更するのではなく、アクションはミューテーションをコミットします。アクションには、任意の非同期コードまたはビジネスロジックを含めることができます。Vuexでは、状態オブジェクトはMutation関数内でのみ変更することを推奨しています。本質的に同期であるため、Mutation関数内で重いコードやブロックするコードを実行しないこともお勧めします
Emmanuel Neni

回答:


221

質問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 (store) {
  store.dispatch('INCREMENT')
}

// a action with additional arguments
// with ES2015 argument destructuring
function incrementBy ({ dispatch }, amount) {
  dispatch('INCREMENT', amount)
}

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

  • 突然変異は状態を修正する唯一の方法です
  • 突然変異はビジネスロジックを気にせず、単に「状態」を気にします
  • アクションはビジネスロジックです
  • アクションは一度に複数のミューテーションをディスパッチでき、ビジネスロジックを実装するだけで、データの変更(ミューテーションによって管理)を気にしません

80
アクションは「ビジネスロジック」であり、一度に複数のミューテーションをディスパッチできるという事実は役立ちます。それが私が探していた答えです。ありがとうございました。
Kobi

11
あなたは「変異をディスパッチする」と言います。突然変異をコミットする正しい表現ではありませんか?
ProblemsOfSumit

4
アクションをディスパッチし、ミューテーションをコミットします。
eirik

4
ディスパッチは、vue 2.0のミューテーションでは機能しなくなりました。アクションでミューテーションをコミットする必要があります。
SKLTFZ 2017

18
@Kaicuiこの回答には、ミューテーションが常に同期的であり、アクションが非同期的である可能性があるという注記がありません。それ以外は良い答えです!
2017年

58

ミューテーションは同期的ですが、アクションは非同期的です。

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


2
これは、実際にtodomvcの例がアクションを使用しない方法について、私が作成するつもりだった質問に答えます。
sksallaj 2017年

7
「あなたの操作が同期している場合は、アクションを必要としない」:それは本当ではないです:あなたがやるあなたが同じモジュールから複数の変異を構成する場合に必要なアクションを、アクションから別のアクションを呼び出すことはできませんので。
Raymundus

1
この答えの明らかなフォローアップは、「それでは、なぜアクションを起こして変異を取り除くのか」
Michael Mrozek、

34

ミューテーションとアクションの背後にある動機を理解することで、いつどのようにどのように使用するかをより適切に判断できると思います。また、「ルール」が曖昧になる状況での不確実性の負担からプログラマーを解放します。それぞれの目的について少し推論した結果、アクションとミューテーションの使用方法は確かに間違っている可能性はあるものの、標準的なアプローチはないと思います。

まず、ミューテーションまたはアクションのいずれかを実行する理由を理解してみましょう。

そもそもなぜ定型を通過するのですか?コンポーネントで直接状態を変更しないのはなぜですか?

厳密に言えばstate、コンポーネントから直接変更できます。これstateは単なるJavaScriptオブジェクトであり、加えた変更を元に戻す魔法のようなものはありません。

// Yes, you can!
this.$store.state['products'].push(product)

ただし、これを行うと、場所全体に状態の変異が散在します。状態を格納している単一のモジュールを開くだけで、それに適用できる操作の種類を一目で確認できなくなります。突然変異を一元化すると、定型句を犠牲にしても、これを解決できます。

// so we go from this
this.$store.state['products'].push(product)

// to this
this.$store.commit('addProduct', {product})

...
// and in store
addProduct(state, {product}){
    state.products.push(product)
}
...

短いものをボイラープレートに置き換える場合は、ボイラープレートも小さくしたいと思うでしょう。したがって、ミューテーションは、ビジネスロジックがほとんどない状態のネイティブ操作の非常に薄いラッパーであることを想定しています。言い換えれば、突然変異はセッターのように主に使用されることを意味します。

変異を一元化したので、状態変化の概要がわかります。ツール(vue-devtools)もその場所を認識しているため、デバッグが容易になります。また、多くのVuexのプラグインは、状態を直接監視して変更を追跡しないので、その変化に依存していることにも注意してください。したがって、状態に対する「範囲外」の変更は、それらからは見えません。

それでmutationsactionsとにかく違いは何ですか?

ミューテーションのようなアクションもストアのモジュールにあり、stateオブジェクトを受け取ることができます。つまり、直接変更することできます。それで、両方を持つことの意味は何ですか?ミューテーションを小さくシンプルに保つ必要があると考える場合、より複雑なビジネスロジックを収容するための代替手段が必要であることを意味します。アクションはこれを行う手段です。また、以前に確立したように、vue-devtoolsとプラグインはMutationsによる変更を認識しているため、一貫性を保つためにアクションからMutationsを使い続ける必要があります。さらに、アクションはすべてを包括することを意図しており、それらがカプセル化するロジックは非同期である可能性があるため、アクションも最初から単純に非同期にすることは理にかなっています。

アクションは非同期である可能性があることをしばしば強調しますが、ミューテーションは通常そうではありません。この違いは、ミューテーションを同期的なもの(および非同期的なアクション)に使用する必要があることを示すものと見なすこともできます。ただし、たとえば、複数のミューテーションを(同期的に)コミットする必要がある場合、またはミューテーションからゲッターを操作する必要がある場合は、ミューテーション関数がゲ​​ッターもミューテーションも引数として受け取らないため、いくつかの問題が発生します...

...興味深い質問につながります。

Mutationがゲッターを受信しないのはなぜですか?

この質問に対する満足のいく答えはまだ見つかりません。コアチームによる説明は、せいぜいわいせつなものだと思いました。それらの使用法を要約すると、ゲッターは状態に対する計算された(そして多くの場合キャッシュされた)拡張機能です。つまり、事前の計算が必要であり、通常は読み取り専用ですが、基本的にはまだ状態です。それは少なくとも彼らが使われるよう奨励されている方法です。

したがって、MutationsがGetterに直接アクセスできないようにすることは、前者から後者が提供するいくつかの機能にアクセスする必要がある場合、次の3つのうちの1つが必要であることを意味します。 Mutation(悪臭)に、または(2)計算値(または関連するGetter自体)が明示的な引数としてMutation(funky)に渡される、または(3)Getterのロジック自体がMutation内で直接複製される、ゲッター(悪臭)によって提供されるキャッシュの追加の利点なし。

以下は(2)の例です。これは、私が遭遇したほとんどのシナリオで「最も悪い」オプションと思われます。

state:{
    shoppingCart: {
        products: []
    }
},

getters:{
    hasProduct(state){
        return function(product) { ... }
    }
}

actions: {
    addProduct({state, getters, commit, dispatch}, {product}){

        // all kinds of business logic goes here

        // then pull out some computed state
        const hasProduct = getters.hasProduct(product)
        // and pass it to the mutation
        commit('addProduct', {product, hasProduct})
    }
}

mutations: {
    addProduct(state, {product, hasProduct}){ 
        if (hasProduct){
            // mutate the state one way
        } else {
            // mutate the state another way 
        }
    }
}

私には、アクションに含まれるコードの一部がMutationの内部ロジックから明らかに染み出ているため、上記は少し複雑であるだけでなく、多少「漏れやすい」ように見えます。

私の意見では、これは妥協の兆候です。Mutationsが自動的にGetterを受信できるようにするには、いくつかの課題があると思います。これは、Vuex自体の設計、またはツール(vue-devtoolsなど)、または下位互換性を維持するため、またはすべての可能性の組み合わせのためです。

私が信じていないのは、ゲッターを自分のミューテーションに渡すことは、必然的に何かが間違っていることを示しているということです。私はそれを、フレームワークの欠点の1つを単に「パッチング」していると考えています。


1
私にとってはそれが最良の答えです。それを読んで初めて、何かを理解したと感じたときに感じる「クリック」がありました。
ロバートKusznier

ゲッターは基本的にcomputed出力されます。これらは読み取り専用です。突然変異を表示するより良い方法は、if elseあなたが持っているものを削除することです。Vuexのドキュメントではcommit、アクション内に複数を格納できるとしています。したがって、ロジックに応じて特定のミューテーションをコミットできると想定するのは論理的です。私は行動をWHICHミューテーションを発動させる方法の1つと見なしています。
Tamb

@Tamb:状態とゲッターの両方がコンテキストデータを提供します。国家をどのように修正するかを決定する前に彼らに質問されることは理にかなっています。その情報がStateから完全にフェッチできる場合、Stateにアクセスできるため、ロジック全体が単一のMutation内にカプセル化されるのは理にかなっています。セッターの標準的な操作手順です。あまり意味がないのは、単に同様の情報をゲッターにクエリする必要があるからといって、根本的に異なるアプローチをとることです。
Michael Ekoka

@Tamb:あなたが示唆しているのは、ゲッターにクエリを実行する必要がある場合、上記のパターンを変更し、選択ロジックを、ゲッターにアクセスして小さなダムの変異の集まりを接着できるプロキシアクションに移動する必要があるということです。それは機能しますが、それでも遠回りであり、私の回答で言及している悪臭に対処していません。
Michael Ekoka

ドキュメントは、状態を計算する必要があるときにゲッターを使用すると述べています。したがって、それらは計算されたプロパティに類似しているので、今日は正しいように見えました。アクションが突然変異を結びつけることができると言って、あなたが何を得ているかを確認してください。ドキュメントは、ビジネスロジックをアクション内に配置することを明確に述べています。
Tamb

15

TLDRの答えは、Mutationsは同期/トランザクションであることを意図していると思います。そのため、Ajax呼び出しを実行する必要がある場合、または他の非同期コードを実行する必要がある場合は、アクションでそれを実行し、その後で変更をコミットして、新しい状態を設定する必要があります。


1
これはドキュメントの要約のように見えます。何も問題はありません。しかし、この回答の問題は、それが主張することが必ずしも真実ではないということです。非同期関数/ AJAXを呼び出すときにミューテーション内の状態を変更できます。これは、完全なコールバックで変更できます。これが、Vuexを使用する場合にアクション使用して開発のベストプラクティスを実現する必要がある理由について、多くの混乱を引き起こしていると思います。私がVuexを使い始めたとき、それは確かに私にとって混乱の原因でした。
Erutan409

8

アクションとミューテーションの主な違い:

  1. アクションの内部では、非同期コードを実行できますが、ミューテーションでは実行できません。したがって、非同期コードのアクションを使用します。それ以外の場合はミューテーションを使用します。
  2. アクションの内部では、ゲッター、ステート、ミューテーション(コミット)、アクションのアクション(ディスパッチ)にアクセスでき、ステートにアクセスできます。したがって、状態のみにアクセスする場合は、ミューテーションを使用します。それ以外の場合はアクションを使用します。

5

による docs

アクションミューテーションに似ていますが、違いは次のとおりです。

  • 状態変化させる代わりに、アクションは 変化をコミットします。
  • アクションには、任意の非同期操作を含めることができます。

次のスニペットを考えてみましょう。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++               //Mutating the state. Must be synchronous
    }
  },
  actions: {
    increment (context) {
      context.commit('increment') //Committing the mutations. Can be asynchronous.
    }
  }
})

アクションハンドラー(increment)は、ストアインスタンスの同じメソッド/プロパティのセットを公開するコンテキストオブジェクトを受け取るため、context.commitを呼び出して変更をコミットするか、context.stateおよびcontext.gettersを介して状態およびゲッターにアクセスできます。


1
vuejsコンポーネントのメソッドである「突然変異」関数からの呼び出しは可能ですか?
AlbertoAcuña19年

@AlbertoAcuña同じ質問があります。それを実行しようとすると、ローカルミューテーションが未定義であるというエラーがスローされます。
Rutwick Gangurde

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


4

突然変異:

Can update the state. (Having the Authorization to change the state).

行動:

Actions are used to tell "which mutation should be triggered"

Redux Wayで

Mutations are Reducers
Actions are Actions

なぜ両方??

アプリケーションが増加し、コーディングとラインが増加する場合、変更は状態を変更する唯一の権限であるため、変更内ではなくアクションでロジックを処理する必要があります。その場合、状態をできるだけきれいにする必要があります。


2

これも私を混乱させたので、簡単なデモを作りました。

component.vue

<template>
    <div id="app">
        <h6>Logging with Action vs Mutation</h6>
        <p>{{count}}</p>
        <p>
            <button @click="mutateCountWithAsyncDelay()">Mutate Count directly with delay</button>
        </p>
        <p>
            <button @click="updateCountViaAsyncAction()">Update Count via action, but with delay</button>
        </p>
        <p>Note that when the mutation handles the asynchronous action, the "log" in console is broken.</p>
        <p>When mutations are separated to only update data while the action handles the asynchronous business
            logic, the log works the log works</p>
    </div>
</template>

<script>

        export default {
                name: 'app',

                methods: {

                        //WRONG
                        mutateCountWithAsyncDelay(){
                                this.$store.commit('mutateCountWithAsyncDelay');
                        },

                        //RIGHT
                        updateCountViaAsyncAction(){
                                this.$store.dispatch('updateCountAsync')
                        }
                },

                computed: {
                        count: function(){
                                return this.$store.state.count;
                        },
                }

        }
</script>

store.js

import 'es6-promise/auto'
import Vuex from 'vuex'
import Vue from 'vue';

Vue.use(Vuex);

const myStore = new Vuex.Store({
    state: {
        count: 0,
    },
    mutations: {

        //The WRONG way
        mutateCountWithAsyncDelay (state) {
            var log1;
            var log2;

            //Capture Before Value
            log1 = state.count;

            //Simulate delay from a fetch or something
            setTimeout(() => {
                state.count++
            }, 1000);

            //Capture After Value
            log2 = state.count;

            //Async in mutation screws up the log
            console.log(`Starting Count: ${log1}`); //NRHG
            console.log(`Ending Count: ${log2}`); //NRHG
        },

        //The RIGHT way
        mutateCount (state) {
            var log1;
            var log2;

            //Capture Before Value
            log1 = state.count;

            //Mutation does nothing but update data
            state.count++;

            //Capture After Value
            log2 = state.count;

            //Changes logged correctly
            console.log(`Starting Count: ${log1}`); //NRHG
            console.log(`Ending Count: ${log2}`); //NRHG
        }
    },

    actions: {

        //This action performs its async work then commits the RIGHT mutation
        updateCountAsync(context){
            setTimeout(() => {
                context.commit('mutateCount');
            }, 1000);
        }
    },
});

export default myStore;

これを調査した結果、突然変異はデータを変更することだけに焦点を当てた慣習であり、問​​題をより適切に分離し、更新されたデータの前後のロギングを改善するという結論に達しました。アクションはより高いレベルのロジックを処理し、適切にミューテーションを呼び出す抽象化のレイヤーです


0

1. ドキュメントから

アクションはミューテーションに似ていますが、違いは次のとおりです。

  • 状態を変化させる代わりに、アクションは変化をコミットします。
  • アクションには、任意の非同期操作を含めることができます。

アクションには非同期操作を含めることができますが、ミューテーションには含めることができません。

2.変異を呼び出し、直接状態を変更できます。また、次のようにしてアクションで状態を変更することもできます。

actions: {
  increment (store) {
    // do whatever ... then change the state
    store.dispatch('MUTATION_NAME')
  }
}

アクションは他のことを処理するように設計されています。そこでは多くのことを実行でき(非同期操作を使用できます)、そこに変異をディスパッチして状態を変更します。


0

変異のない状態はないからです!コミットされると、予測可能な方法で状態を変更するロジックの一部が実行されます。突然変異は状態を設定または変更する唯一の方法です(そのため、直接的な変更はありません)。さらに、それらは同期している必要があります。このソリューションは非常に重要な機能を駆動します。変異はdevtoolsにログインしています。そしてそれはあなたに素晴らしい読みやすさと予測可能性を提供します!

もう1つ、アクションです。言われているように、アクションは突然変異をコミットします。したがって、ストアを変更することはなく、これらを同期させる必要はありません。ただし、非同期ロジックの余分な部分を管理できます。


0

たとえば、actionsを呼び出すだけの追加のレイヤーをmutations用意する必要はないようです。

const actions = {
  logout: ({ commit }) => {
    commit("setToken", null);
  }
};

const mutations = {
  setToken: (state, token) => {
    state.token = token;
  }
};

では、actionscallsを呼び出す場合はlogout、ミューテーション自体を呼び出しませんか?

アクションの全体的な考え方は、1つのアクションの内部から複数のミューテーションを呼び出すか、Ajaxリクエストまたは想像できるあらゆる種類の非同期ロジックを作成することです。

最終的には、複数のネットワークリクエストを作成し、最終的に多くの異なるミューテーションを呼び出すアクションが発生する可能性があります。

ですから、私たちにVuex.Store()はできるだけ複雑なものを詰め込もうとしています。actionsこれmutationsによりstategettersよりクリーンでわかりやすくなり、VueやReactなどのライブラリを人気のあるものにする種類のモジュール性と一致します。


0

私は約3年間Vuexを専門的に使用してきましたが、ここでは、アクションとミューテーションの本質的な違い、それらを上手に併用することでどのように利益を得ることができるか、そしてどのように生活をより困難にすることができるかについて理解したと思います。うまく利用しないでください。

Vuexの主な目的は、アプリケーションの動作を制御するための新しいパターンである反応性を提供することです。アイデアは、アプリケーションの状態のオーケストレーションを特殊なオブジェクトであるストアにオフロードすることです。コンポーネントをストアデータに直接接続して、都合のよいときに使用できるメソッドを提供します。これにより、コンポーネントはその仕事に集中できます。つまり、ユーザーに提示するテンプレート、スタイル、および基本的なコンポーネントの動作を定義します。その間、ストアは重いデータロードを処理します。

ただし、このパターンの利点はそれだけではありません。ストアがアプリケーション全体の単一のデータソースであるという事実は、多くのコンポーネント間でこのデータを再利用できる大きな可能性を提供します。これは、クロスコンポーネント通信のこの問題に対処しようとする最初のパターンではありませんが、優れているのは、コンポーネントにこの共有データの状態を変更することを基本的に禁止することにより、アプリケーションに非常に安全な動作を実装することを強制することです。 、代わりに「パブリックエンドポイント」を使用して変更を要求するように強制します。

基本的な考え方はこれです:

  • ストアには内部状態があり、コンポーネントから直接アクセスすることはできません(mapStateは事実上禁止されています)。
  • ストアには、内部状態への同期変更である変更があります。ミューテーションの唯一の仕事は、状態を変更することです。アクションからのみ呼び出す必要があります。それらは、状態に起こったことを説明するために名前を付ける必要があります(ORDER_CANCELED、ORDER_CREATED)。それらは短くて甘いものにしてください。Vue Devtoolsブラウザー拡張機能を使用して、それらをステップ実行できます(デバッグにも最適です!)
  • ストアには、非同期であるか、promiseを返すアクションもあります。これらは、コンポーネントがアプリケーションの状態を変更するときに呼び出すコンポーネントのアクションです。ビジネス指向のアクション(動詞、つまり、cancelOrder、createOrder)で名前を付ける必要があります。ここで、リクエストを検証して送信します。状態を変更する必要がある場合、各アクションは異なるステップで異なるコミットを呼び出すことがあります。
  • 最後に、ストアにはゲッターがあり、コンポーネントに状態を公開するために使用します。アプリケーションの拡張に伴い、多くのコンポーネントで頻繁に使用されることを期待してください。Vuexは、無駄な計算サイクルを回避するためにゲッターを頻繁にキャッシュします(ゲッターにパラメーターを追加しない限り-パラメーターを使用しないようにしてください)。アプリケーションが現在どのような状態にあるかをできるだけ詳しく表す名前を付けるようにしてください。

とはいえ、この方法でアプリケーションの設計を開始すると、魔法が始まります。例えば:

  • ユーザーに注文のリストを提供するコンポーネントがあり、それらの注文を削除する可能性があります
  • コンポーネントは、IDを持つオブジェクトの配列であるストアゲッター(deletableOrders)をマップしました
  • コンポーネントには、注文の各行にボタンがあり、そのクリックは、注文オブジェクトを渡すストアアクション(deleteOrder)にマップされます(覚えておくと、ストアのリスト自体に由来します)。
  • ストアのdeleteOrderアクションは次のことを行います。
    • 削除を検証します
    • 削除する注文を一時的に保存します
    • 注文とともにORDER_DELETEDミューテーションをコミットします
    • API呼び出しを送信して実際に注文を削除します(はい、状態を変更した後で!)
    • 呼び出しが終了するまで待機し(状態は既に更新されています)、失敗すると、以前に保持した順序でORDER_DELETE_FAILEDミューテーションを呼び出します。
  • ORDER_DELETEDミューテーションは、削除可能なオーダーのリストから指定されたオーダーを単に削除します(ゲッターを更新します)
  • ORDER_DELETE_FAILEDミューテーションは単にそれを元に戻し、状態を変更してエラーを通知します(別のコンポーネント、エラー通知はその状態を追跡して、いつそれ自体を表示するかを知っています)

結局、私たちは「反応的」とみなされるユーザー体験を持っています。ユーザーの観点から、アイテムはすぐに削除されました。ほとんどの場合、エンドポイントが機能することを期待しているので、これは完璧です。失敗した場合でも、実際のデータを使用してフロントエンドアプリケーションの状態の問題を分離することができたため、アプリケーションの反応をある程度制御できます。

いつもお店が必要なわけではありません。次のようなストアを作成している場合:

export default {
  state: {
    orders: []
  },
  mutations: {
    ADD_ORDER (state, order) {
       state.orders.push(order)
    },
    DELETE_ORDER (state, orderToDelete) {
       state.orders = state.orders.filter(order => order.id !== orderToDelete.id)
    }
  },
  actions: {
    addOrder ({commit}, order) {
      commit('ADD_ORDER', order)
    },
    deleteOrder ({commit}, order) {
      commit('DELETE_ORDER', order)
    }
  },
  getters: {
    orders: state => state.orders
  }
}

私には、ストアをデータストアとしてのみ使用しており、アプリケーションが反応する変数の制御も行わないようにすることにより、おそらくその反応性の側面を見逃しているようです。基本的に、コンポーネントに記述されたコード行をストアにオフロードすることができ、おそらくオフロードする必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.