54

ディスパッチとコミットをいつ使用するかを誰か説明できますか?

コミットがミューテーションをトリガーし、ディスパッチがアクションをトリガーすることを理解しています。

しかし、派遣もアクションの一種ではないでしょうか。

4

1 に答える 1

136

あなたが正しく言ったように$dispatch、アクションをcommitトリガーし、ミューテーションをトリガーします。これらの概念を使用する方法は次のとおりです。

$dispatchルート/コンポーネントのメソッドから常に使用します。$dispatchいくつかのアクションを実行するために、vuex ストアにメッセージを送信します。フロントエンドのパフォーマンスが影響を受けないように、アクションは現在の tickの後にいつでも実行できます。

commitコンポーネント/ルートのいずれからも決して使用しません。アクション内からのみ、コミットするデータがある場合にのみ実行されます。理由: コミットは同期的であり、完了するまでフロントエンドがフリーズする可能性があります。

このケースを考えてみましょう: サーバーから json データを取得する必要がある場合。この場合、これを非同期で実行して、ユーザー インターフェイスが応答しなくなったり、しばらくフリーズしたりしないようにする必要があります。したがって、単に$dispatchアクションを実行し、それが後で実行されることを期待します。あなたのアクションがこのタスクを引き受け、サーバーからデータをロードし、後で状態を更新します。

それまで ajax スピナーを表示できるように、アクションがいつ終了するかを知る必要がある場合は、以下で説明するように Promise を返すことができます (例: 現在のユーザーを読み込む)。

「loadCurrentUser」アクションを定義する方法は次のとおりです。

actions: {
    loadCurrentUser(context) {
        // Return a promise so that calling method may show an AJAX spinner gif till this is done
        return new Promise((resolve, reject) => {
            // Load data from server
            // Note: you cannot commit here, the data is not available yet
            this.$http.get("/api/current-user").then(response => {
                // The data is available now. Finally we can commit something
                context.commit("saveCurrentUser", response.body)  // ref: vue-resource docs
                // Now resolve the promise
                resolve()
            }, response => {
                // error in loading data
                reject()
            })
        })
    },
    // More actions
}

ミューテーション ハンドラーでは、アクションから発生するすべてのコミットを行います。「saveCurrentUser」コミットを定義する方法は次のとおりです。

mutations: {
    saveCurrentUser(state, data) {
        Vue.set(state, "currentUser", data)
    },
    // More commit-handlers (mutations)
}

コンポーネントでcreatedまたはmountedの場合、以下に示すようにアクションを呼び出すだけです。

mounted: function() {
    // This component just got created. Lets fetch some data here using an action
    // TODO: show ajax spinner before dispatching this action
    this.$store.dispatch("loadCurrentUser").then(response => {
        console.log("Got some data, now lets show something in this component")
        // TODO: stop the ajax spinner, loading is done at this point.
    }, error => {
        console.error("Got nothing from server. Prompt user to check internet connection and try again")
    })
}

上記のように Promise を返すことは完全にオプションであり、誰もが好まない設計上の決定でもあります。Promise を返すかどうかについての詳細な議論については、この回答の下のコメントを読むことができます: https://stackoverflow.com/a/40167499/654825

于 2016-11-03T04:09:27.230 に答える