ディスパッチを使用するか、コミットを使用するかを誰かが説明できますか?
コミットが変異を引き起こし、ディスパッチがアクションを引き起こすことを理解しています。
ただし、ディスパッチはアクションの一種でもありませんか?
あなたが正しく言ったように、$dispatch
はアクションをトリガーし、commit
は突然変異をトリガーします。これらの概念の使用方法は次のとおりです。
ルート/コンポーネントのメソッドから常に$dispatch
を使用します。 $dispatch
は、アクションを実行するためにメッセージをvuexストアに送信します。フロントエンドのパフォーマンスに影響を与えないように、アクションはcurrent tickの後にいつでも実行できます。
コンポーネント/ルートのいずれからもcommit
することはありません。アクション内からonly、コミットするデータがある場合はonlyが行われます。理由:コミットはsynchronousで、完了するまでフロントエンドをフリーズする可能性があります。
このケースを考えてみましょう:サーバーから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