Dalam Vuex, apa logika memiliki "tindakan" dan "mutasi?"
Saya memahami logika komponen yang tidak dapat mengubah keadaan (yang tampaknya pintar), tetapi memiliki kedua tindakan dan mutasi sepertinya Anda sedang menulis satu fungsi untuk memicu fungsi lainnya, untuk kemudian mengubah keadaan.
Apa perbedaan antara "aksi" dan "mutasi," bagaimana mereka bekerja bersama, dan lebih lagi, saya ingin tahu mengapa pengembang Vuex memutuskan untuk melakukannya dengan cara ini?
mutations
danactions
didefinisikan dalam dokumentasi vuex sebagai metode mengubah negara. Anda tidak perlu melakukan tindakan untuk melakukan mutasi.Jawaban:
Pertanyaan 1 : Mengapa pengembang Vuejs memutuskan untuk melakukannya dengan cara ini?
Menjawab:
Pertanyaan 2 : Apa perbedaan antara "aksi" dan "mutasi"?
Mari kita simak dulu penjelasan resminya:
Inilah penjelasan saya tentang hal di atas:
sumber
Mutasi bersifat sinkron, sedangkan tindakan bisa asinkron.
Dengan kata lain: Anda tidak perlu melakukan tindakan jika operasi Anda sinkron, jika tidak, implementasikan.
sumber
Saya percaya bahwa memiliki pemahaman tentang motivasi di balik Mutasi dan Tindakan memungkinkan seseorang untuk menilai dengan lebih baik kapan harus menggunakan mana dan bagaimana. Ini juga membebaskan programmer dari beban ketidakpastian dalam situasi di mana "aturan" menjadi kabur. Setelah beralasan tentang tujuan mereka masing-masing, saya sampai pada kesimpulan bahwa meskipun mungkin ada cara yang salah untuk menggunakan Tindakan dan Mutasi, saya tidak berpikir bahwa ada pendekatan kanonik.
Pertama-tama mari kita mencoba memahami mengapa kita melakukan mutasi atau tindakan.
Sebenarnya Anda dapat mengubah
state
langsung dari komponen Anda. Inistate
hanyalah objek JavaScript dan tidak ada yang ajaib yang akan mengembalikan perubahan yang Anda buat padanya.Namun, dengan melakukan ini, Anda menyebarkan mutasi negara Anda di semua tempat. Anda kehilangan kemampuan untuk hanya membuka satu modul untuk perumahan negara dan sekilas melihat jenis operasi apa yang dapat diterapkan untuk itu. Setelah mutasi terpusat menyelesaikan ini, meskipun dengan biaya beberapa boilerplate.
Saya pikir jika Anda mengganti sesuatu yang pendek dengan boilerplate, Anda ingin boilerplate juga kecil. Karena itu saya berasumsi bahwa mutasi dimaksudkan untuk menjadi pembungkus yang sangat tipis di sekitar operasi asli di negara bagian, dengan hampir tidak ada logika bisnis. Dengan kata lain, mutasi dimaksudkan untuk sebagian besar digunakan seperti setter.
Sekarang, karena Anda telah memusatkan mutasi Anda, Anda memiliki gambaran yang lebih baik tentang perubahan status Anda dan karena tooling Anda (vue-devtools) juga mengetahui lokasi itu, menjadikan proses debug menjadi lebih mudah. Perlu juga diingat bahwa banyak plugin Vuex tidak menonton negara secara langsung untuk melacak perubahan, mereka lebih mengandalkan mutasi untuk itu. Perubahan-perubahan "tidak terikat" pada negara dengan demikian tidak terlihat oleh mereka.
Tindakan, seperti mutasi, juga berada di modul toko dan dapat menerima
state
objek. Yang menyiratkan bahwa mereka juga bisa bermutasi secara langsung. Jadi apa gunanya memiliki keduanya? Jika kita beralasan bahwa mutasi harus dijaga tetap kecil dan sederhana, itu menyiratkan bahwa kita memerlukan sarana alternatif untuk menampung logika bisnis yang lebih rumit. Tindakan adalah cara untuk melakukan ini. Dan karena seperti yang telah kita ketahui sebelumnya, vue-devtools dan plugins menyadari perubahan melalui Mutasi, agar tetap konsisten kita harus terus menggunakan Mutasi dari tindakan kita. Lebih jauh, karena tindakan dimaksudkan untuk mencakup semua dan bahwa logika yang mereka enkapsulasi mungkin tidak sinkron, maka masuk akal jika Tindakan juga akan dibuat tidak sinkron sejak awal.Sering ditekankan bahwa tindakan bisa tidak sinkron, sedangkan mutasi biasanya tidak. Anda dapat memutuskan untuk melihat perbedaan sebagai indikasi bahwa mutasi harus digunakan untuk apa pun yang sinkron (dan tindakan untuk apa pun yang tidak sinkron); Namun, Anda akan mengalami beberapa kesulitan jika misalnya Anda perlu melakukan lebih dari satu mutasi (secara serempak), atau jika Anda perlu bekerja dengan Getter dari mutasi Anda, karena fungsi mutasi tidak menerima Getters atau Mutations sebagai argumen ...
... yang mengarah ke pertanyaan menarik.
Saya belum menemukan jawaban yang memuaskan untuk pertanyaan ini. Saya telah melihat beberapa penjelasan oleh tim inti yang saya temukan terbaik diperdebatkan. Jika saya merangkum penggunaannya, Getters dimaksudkan untuk dihitung (dan sering di-cache) ekstensi ke status. Dengan kata lain, mereka pada dasarnya masih keadaan, meskipun itu memerlukan beberapa perhitungan dimuka dan mereka biasanya hanya baca. Setidaknya itulah cara mereka didorong untuk digunakan.
Dengan demikian, mencegah Mutasi dari mengakses langsung Getters berarti bahwa satu dari tiga hal sekarang diperlukan, jika kita perlu mengakses dari yang sebelumnya beberapa fungsi yang ditawarkan oleh yang terakhir: (1) salah satu perhitungan keadaan yang disediakan oleh Getter digandakan di suatu tempat yang dapat diakses ke Mutasi (bau tak sedap), atau (2) nilai yang dihitung (atau Getter yang relevan itu sendiri) diturunkan sebagai argumen eksplisit terhadap Mutasi (funky), atau (3) logika Getter sendiri digandakan langsung dalam Mutasi , tanpa manfaat tambahan dari caching seperti yang diberikan oleh Getter (bau busuk).
Berikut ini adalah contoh (2), yang dalam kebanyakan skenario yang saya temui tampaknya merupakan opsi "paling buruk".
Bagi saya, di atas tampaknya tidak hanya sedikit berbelit-belit, tetapi juga agak "bocor", karena beberapa kode yang ada dalam Aksi jelas mengalir dari logika internal Mutasi.
Menurut pendapat saya, ini merupakan indikasi kompromi. Saya percaya bahwa memungkinkan Mutasi untuk secara otomatis menerima Getters menghadirkan beberapa tantangan. Ini dapat berupa desain Vuex sendiri, atau tooling (vue-devtools et al), atau untuk mempertahankan beberapa kompatibilitas, atau kombinasi dari semua kemungkinan yang dinyatakan.
Apa yang saya tidak percaya adalah bahwa menyerahkan Surat kepada Mutasi Anda sendiri adalah pertanda bahwa Anda melakukan sesuatu yang salah. Saya melihatnya hanya sebagai "menambal" salah satu kelemahan kerangka kerja.
sumber
computed
keluaran. Mereka hanya baca. Cara yang lebih baik untuk melihat mutasi bisa dengan menghapus yangif else
Anda miliki. Dokumentasi vuex mengatakan Anda dapat menampung lebih dari 1commit
di dalam suatu tindakan. Jadi akan logis untuk berasumsi Anda dapat melakukan mutasi tertentu tergantung pada logika. Saya melihat tindakan sebagai cara untuk menentukan mutasi WHICH ke api.Saya pikir jawaban TLDR adalah bahwa Mutasi dimaksudkan untuk sinkron / transaksional. Jadi, jika Anda perlu menjalankan panggilan Ajax, atau melakukan kode asinkron lainnya, Anda harus melakukannya dalam suatu Tindakan, dan kemudian melakukan mutasi setelahnya, untuk mengatur keadaan baru.
sumber
Perbedaan utama antara Tindakan dan Mutasi:
sumber
Menurut
docs
Tindakannya mirip dengan mutasi , perbedaannya adalah:
Pertimbangkan cuplikan berikut.
sumber
Penafian - Saya baru saja mulai menggunakan vuejs jadi ini hanya saya yang mengekstrapolasi maksud desain.
Debugging mesin waktu menggunakan snapshots dari negara, dan menunjukkan garis waktu tindakan dan mutasi. Secara teori kita bisa saja
actions
bersama dengan rekaman negara setter dan getter untuk secara sinkron menggambarkan mutasi. Tapi kemudian:mutations
transaksi tetapi kemudian kita dapat mengatakan transaksi perlu ditingkatkan sebagai lawan dari kondisi perlombaan dalam tindakan. Mutasi anonim di dalam suatu tindakan bisa lebih mudah muncul kembali bug semacam ini karena pemrograman async rapuh dan sulit.Bandingkan log transaksi berikut dengan mutasi bernama.
Dengan log transaksi yang tidak memiliki mutasi bernama:
Saya harap Anda dapat memperkirakan dari contoh itu potensi penambahan kompleksitas dalam aksi async dan anonim di dalam tindakan.
https://vuex.vuejs.org/en/mutations.html
sumber
Mutasi:
Tindakan:
Dalam Redux Way
Kenapa Keduanya ??
Ketika aplikasi tumbuh, pengkodean dan garis akan meningkat, Saat itu Anda harus menangani logika dalam Tindakan tidak dalam mutasi karena mutasi adalah satu-satunya otoritas untuk mengubah keadaan, itu harus sebersih mungkin.
sumber
Ini juga membingungkan saya, jadi saya membuat demo sederhana.
komponen.vue
store.js
Setelah meneliti ini, kesimpulan yang saya dapatkan adalah bahwa mutasi adalah konvensi yang berfokus hanya pada perubahan data untuk memisahkan masalah yang lebih baik dan meningkatkan logging sebelum dan sesudah data yang diperbarui. Sedangkan tindakan adalah lapisan abstraksi yang menangani logika tingkat yang lebih tinggi dan kemudian memanggil mutasi dengan tepat
sumber
1.Dari dokumen :
Tindakan dapat berisi operasi asinkron, tetapi mutasi tidak bisa.
2. Kami meminta mutasi, kita dapat mengubah negara secara langsung. dan kita juga bisa dalam aksi mengubah status dengan seperti ini:
Tindakan dirancang untuk menangani lebih banyak hal lain, kita dapat melakukan banyak hal di sana (kita dapat menggunakan operasi asinkron) kemudian mengubah keadaan dengan mengirimkan mutasi di sana.
sumber
Karena tidak ada keadaan tanpa mutasi! Ketika dilakukan - sepotong logika, yang mengubah keadaan dengan cara yang dapat diduga, dieksekusi. Mutasi adalah satu-satunya cara untuk mengatur atau mengubah keadaan (jadi tidak ada perubahan langsung!), Dan selanjutnya - mereka harus sinkron. Solusi ini menggerakkan fungsi yang sangat penting: mutasi masuk ke devtools. Dan itu memberi Anda keterbacaan dan prediksi yang bagus!
Satu hal lagi - tindakan. Seperti yang telah dikatakan - tindakan melakukan mutasi. Jadi mereka tidak mengubah toko, dan tidak perlu ini sinkron. Tapi, mereka dapat mengelola bagian tambahan dari logika asinkron!
sumber
Tampaknya tidak perlu memiliki lapisan tambahan
actions
hanya untuk memanggilmutations
, misalnya:Jadi jika menelepon
actions
panggilanlogout
, mengapa tidak memanggil mutasi itu sendiri?Seluruh gagasan tindakan adalah untuk memanggil beberapa mutasi dari dalam satu tindakan atau membuat permintaan Ajax atau segala jenis logika asinkron yang dapat Anda bayangkan.
Kami mungkin pada akhirnya memiliki tindakan yang membuat beberapa permintaan jaringan dan akhirnya memanggil banyak mutasi berbeda.
Jadi kami mencoba untuk memasukkan sebanyak mungkin kerumitan dari kami
Vuex.Store()
di kamiactions
dan ini meninggalkan kamimutations
,state
dangetters
lebih bersih dan langsung dan jatuh sejalan dengan jenis modularitas yang membuat perpustakaan seperti Vue dan React populer.sumber
Saya telah menggunakan Vuex secara profesional selama sekitar 3 tahun, dan di sini saya pikir saya telah menemukan perbedaan mendasar antara tindakan dan mutasi, bagaimana Anda bisa mendapat manfaat dari menggunakannya bersama-sama, dan bagaimana Anda dapat membuat hidup Anda lebih sulit jika Anda jangan menggunakannya dengan baik.
Tujuan utama Vuex adalah menawarkan pola baru untuk mengontrol perilaku aplikasi Anda: Reaktivitas. Idenya adalah untuk menurunkan orkestrasi keadaan aplikasi Anda ke objek khusus: toko. Ini dengan mudah memasok metode untuk menghubungkan komponen Anda langsung ke data toko Anda untuk digunakan sesuka mereka. Ini memungkinkan komponen Anda untuk fokus pada pekerjaan mereka: mendefinisikan templat, gaya, dan perilaku komponen dasar untuk disajikan kepada pengguna Anda. Sementara itu, toko menangani beban data yang berat.
Itu bukan hanya satu-satunya keuntungan dari pola ini. Fakta bahwa toko adalah sumber data tunggal untuk keseluruhan aplikasi Anda menawarkan potensi besar kegunaan kembali data ini di banyak komponen. Ini bukan pola pertama yang mencoba untuk mengatasi masalah ini komunikasi lintas-komponen, tetapi di mana itu bersinar adalah bahwa itu memaksa Anda untuk menerapkan perilaku yang sangat aman untuk aplikasi Anda dengan pada dasarnya melarang komponen Anda untuk mengubah keadaan data yang dibagikan ini , dan paksakan untuk menggunakan "titik akhir publik" untuk meminta perubahan.
Ide dasarnya adalah ini:
Yang sedang berkata, keajaiban dimulai ketika kita mulai merancang aplikasi kita dengan cara ini. Sebagai contoh:
Pada akhirnya, kami memiliki pengalaman pengguna yang dianggap "reaktif". Dari perspektif pengguna kami, item telah dihapus segera. Sebagian besar waktu, kami berharap titik akhir kami hanya berfungsi, jadi ini sempurna. Ketika gagal, kami masih memiliki beberapa kontrol atas bagaimana aplikasi kami akan bereaksi , karena kami telah berhasil memisahkan kekhawatiran keadaan aplikasi front-end kami, dengan data aktual.
Anda tidak selalu membutuhkan toko, ingatlah. Jika Anda menemukan bahwa Anda sedang menulis toko yang terlihat seperti ini:
Bagi saya sepertinya Anda hanya menggunakan store sebagai data store, dan mungkin kehilangan aspek reaktivitasnya, dengan tidak membiarkannya juga mengendalikan variabel yang bereaksi terhadap aplikasi Anda. Pada dasarnya, Anda dapat dan mungkin harus menurunkan beberapa baris kode yang ditulis dalam komponen Anda ke toko Anda.
sumber