actions
di Vuex tidak sinkron. Satu-satunya cara agar fungsi pemanggil (pemrakarsa tindakan) mengetahui bahwa suatu tindakan telah selesai - adalah dengan mengembalikan Janji dan menyelesaikannya nanti.
Berikut ini contohnya: myAction
mengembalikan a Promise
, membuat panggilan http dan menyelesaikan atau menolak Promise
nanti - semua secara asinkron
actions: {
myAction(context, data) {
return new Promise((resolve, reject) => {
// Do something here... lets say, a http call using vue-resource
this.$http("/api/something").then(response => {
// http success, call the mutator and change something in state
resolve(response); // Let the calling function know that http is done. You may send some data back
}, error => {
// http failed, let the calling function know that action did not work out
reject(error);
})
})
}
}
Sekarang, ketika komponen Vue Anda dimulai myAction
, ia akan mendapatkan objek Promise ini dan dapat mengetahui apakah berhasil atau tidak. Berikut beberapa contoh kode untuk komponen Vue:
export default {
mounted: function() {
// This component just got created. Lets fetch some data here using an action
this.$store.dispatch("myAction").then(response => {
console.log("Got some data, now lets show something in this component")
}, error => {
console.error("Got nothing from server. Prompt user to check internet connection and try again")
})
}
}
Seperti yang Anda lihat di atas, sangat bermanfaat untuk actions
mengembalikan file Promise
. Jika tidak, tidak ada cara bagi pemrakarsa tindakan untuk mengetahui apa yang terjadi dan kapan semuanya cukup stabil untuk menampilkan sesuatu di antarmuka pengguna.
Dan catatan terakhir tentang mutators
- seperti yang Anda tunjukkan dengan benar, mereka sinkron. Mereka mengubah barang di state
, dan biasanya dipanggil dari actions
. Tidak perlu untuk campuran Promises
dengan mutators
, sebagai actions
pegangan bagian.
Sunting: Pandangan saya tentang siklus Vuex dari aliran data satu arah:
Jika Anda mengakses data seperti this.$store.state["your data key"]
di komponen Anda, maka aliran datanya searah.
Janji dari tindakan hanya untuk memberi tahu komponen bahwa tindakan telah selesai.
Komponen dapat mengambil data dari fungsi penyelesaian janji dalam contoh di atas (bukan uni-directional, oleh karena itu tidak disarankan), atau langsung dari $store.state["your data key"]
yang unidirectional dan mengikuti siklus hidup data vuex.
Paragraf di atas mengasumsikan mutator Anda menggunakan Vue.set(state, "your data key", http_data)
, setelah panggilan http selesai dalam tindakan Anda.
Promise.reject()
.failed
mutator yang disetelstate.foo.failed = true
, yang dapat ditangani oleh komponen. Tidak perlu janji untuk diteruskan ke komponen untuk itu, dan sebagai bonus, apa pun yang ingin bereaksi terhadap kegagalan yang sama dapat melakukannya dari toko juga.{isLoading:true}
di negara bagian saya, dan karena itu menggunakan Promises. Preferensi Anda mungkin berbeda. Pada akhirnya, tujuan kami adalah menulis kode yang bebas kekacauan dan dapat dipelihara. Apakah janji mencapai tujuan itu, atau status vuex - diserahkan kepada pengembang individu dan tim untuk memutuskan.Hanya untuk informasi tentang topik tertutup: Anda tidak perlu membuat janji, axios mengembalikannya sendiri:
Ref: https://forum.vuejs.org/t/how-to-resolve-a-promise-object-in-a-vuex-action-and-redirect-to-another-route/18254/4
Contoh:
Contoh lain:
Contoh lain dengan async-await
sumber
Tindakan
Komponen
sumber
TL: DR; mengembalikan janji dari tindakan Anda hanya jika diperlukan, tetapi KERING yang merangkai tindakan yang sama.
Untuk waktu yang lama saya juga berpikir bahwa tindakan kembali bertentangan dengan siklus Vuex aliran data satu arah.
Tapi, ada KASUS TEPI di mana mengembalikan janji dari tindakan Anda mungkin "perlu".
Bayangkan situasi di mana suatu tindakan dapat dipicu dari 2 komponen berbeda, dan masing-masing menangani kasus kegagalan secara berbeda. Dalam hal ini, seseorang harus meneruskan komponen pemanggil sebagai parameter untuk menyetel tanda yang berbeda di penyimpanan.
Contoh bodoh
Halaman di mana pengguna dapat mengedit nama pengguna di navbar dan di / halaman profil (yang berisi navbar). Keduanya memicu tindakan "ubah nama pengguna", yang tidak sinkron. Jika promise gagal, halaman seharusnya hanya menampilkan error di komponen tempat pengguna mencoba mengubah nama penggunanya.
Tentu saja ini adalah contoh yang bodoh, tetapi saya tidak melihat cara untuk menyelesaikan masalah ini tanpa menduplikasi kode dan melakukan panggilan yang sama dalam 2 tindakan berbeda.
sumber
actions.js
home.vue
sumber