Mutasyonların ve Eylemlerin ardındaki motivasyonları anlamanın, hangisini ve nasıl kullanacağını daha iyi yargılayabileceğine inanıyorum. Ayrıca "kuralların" bulanıklaştığı durumlarda programlayıcıyı belirsizlik yükünden kurtarır. İlgili amaçları hakkında biraz düşündükten sonra, Eylemler ve Mutasyonları kullanmanın kesinlikle yanlış yolları olsa da, kanonik bir yaklaşım olduğunu düşünmediğim sonucuna vardım.
Önce neden Mutasyonlar veya Eylemler'den geçtiğimizi anlamaya çalışalım.
Neden ilk önce kazan plakasından geçmelisiniz? Neden doğrudan bileşenlerdeki durumu değiştirmiyorsunuz?
Kesinlikle söylemek gerekirse state
doğrudan bileşenlerinizden değiştirebilirsiniz. Bu state
sadece bir JavaScript nesnesidir ve üzerinde yaptığınız değişiklikleri geri alacak büyülü bir şey yoktur.
// Yes, you can!
this.$store.state['products'].push(product)
Ancak, bunu yaparak devlet mutasyonlarınızı her yere dağıtırsınız. Sadece durumu barındıran tek bir modülü açma yeteneğini kaybedersiniz ve bir bakışta ne tür işlemlerin uygulanabileceğini görürsünüz. Merkezi mutasyonlara sahip olmak, bazı kazanların maliyeti de olsa bunu çözer.
// 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)
}
...
Sanırım kısa bir şeyi kazan plakasıyla değiştirirseniz, kazan plakasının da küçük olmasını isteyeceksiniz. Bu nedenle mutasyonların, devlet üzerindeki yerel operasyonlar etrafında, neredeyse hiç iş mantığı olmadan çok ince sarıcılar olduğunu varsayıyorum. Başka bir deyişle, mutasyonlar çoğunlukla seterler gibi kullanılmalıdır.
Mutasyonlarınızı merkezileştirdiğinize göre, durum değişiklikleriniz hakkında daha iyi bir genel bakışa sahip olursunuz ve takımlarınız (vue-devtools) da bu konumun farkında olduğundan hata ayıklamayı kolaylaştırır. Ayrıca, birçok Vuex'in eklentisinin, değişiklikleri izlemek için doğrudan durumu izlemediğini, bunun için mutasyonlara bel bağladığını unutmayın. Devletteki "sınır dışı" değişiklikler bu nedenle onlar tarafından görülemez.
Peki mutations
, actions
fark ne?
Mutasyonlar gibi eylemler de mağazanın modülünde bulunur ve state
nesneyi alabilir . Bu da onların ima olabilir ayrıca doğrudan mutasyona. Her ikisine birden sahip olmanın anlamı nedir? Mutasyonların küçük ve basit tutulması gerektiğini düşünürsek, daha ayrıntılı iş mantığını barındırmak için alternatif bir yola ihtiyacımız olduğunu ima eder. Eylemler bunu yapmanın yollarıdır. Ve daha önce belirlediğimiz gibi, vue-devtools ve eklentiler Mutasyonlar yoluyla yapılan değişikliklerin farkında olduğundan, tutarlı kalmak için eylemlerimizden Mutasyonları kullanmaya devam etmeliyiz. Ayrıca, eylemlerin hepsi kapsayıcı olması ve kapsadıkları mantığın eşzamansız olabilmesi nedeniyle, İşlemlerin başlangıçtan itibaren eşzamansız hale getirilmesi mantıklıdır.
Genellikle eylemlerin eşzamansız olabileceği vurgulanırken, mutasyonlar genellikle değildir. Ayrımı, mutasyonların eşzamanlı her şey için (ve eşzamansız her şey için eylemler) kullanılması gerektiğinin bir göstergesi olarak görmeye karar verebilirsiniz; ancak, örneğin birden fazla mutasyon (eşzamanlı olarak) yapmanız gerekiyorsa veya mutasyonlarınızdan bir Getter ile çalışmanız gerekiyorsa, mutasyon işlevleri argüman olarak Getters veya Mutasyonları almadığı için bazı zorluklarla karşılaşırsınız ...
... bu ilginç bir soruya yol açıyor.
Mutasyonlar neden Mektup almıyor?
Bu soruya henüz tatmin edici bir cevap bulamadım. Çekirdek ekip tarafından en çok tartıştığım bir açıklama gördüm. Kullanımlarını özetlersem, Getters durum uzantılarının hesaplanması (ve genellikle önbelleğe alınması) anlamına gelir. Başka bir deyişle, açık bir hesaplama gerektirse de, temelde hala devlettirler ve normalde salt okunurdurlar. En azından bu şekilde kullanılmaları teşvik ediliyor.
Bu nedenle, Mutasyonların doğrudan Getters'a erişmesini engellemek, şimdi üç şeyden birinin gerekli olduğu anlamına gelir, eğer ikincisinden sunulan bazı işlevlere erişmemiz gerekirse: (1) Getter tarafından sağlanan durum hesaplamaları erişilebilir bir yerde çoğaltılır Mutasyona (kötü koku) veya (2) hesaplanan değer (veya ilgili Getter'ın kendisi) Mutasyona (funky) açık bir argüman olarak aktarılır veya (3) Getter'in mantığının kendisi doğrudan Mutasyon içinde çoğaltılır , Getter (kokusu) tarafından sağlanan önbellekleme avantajı olmadan.
Aşağıda, karşılaştığım çoğu senaryoda "en az kötü" seçenek gibi görünen (2) örneği verilmiştir.
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
}
}
}
Bana göre, yukarıdakiler sadece biraz kıvrımlı değil, aynı zamanda bir şekilde "sızdıran" gibi görünüyor, çünkü Eylemde bulunan kodun bir kısmı Mutasyonun iç mantığından açıkça sızıyor.
Bence bu bir uzlaşma göstergesi. Mutasyonların otomatik olarak Getters almasına izin vermenin bazı zorluklar getirdiğine inanıyorum. Vuex'in kendisi ya da alet (vue-devtools et al) tasarımı ya da geriye dönük uyumluluk ya da belirtilen tüm olasılıkların bir kombinasyonunu korumak olabilir.
İnanmadığım şey, Mutasyonlarınıza kendinizin geçmesi, mutlaka yanlış bir şey yaptığınızın bir işaretidir. Bunu çerçevenin eksikliklerinden biri olarak "yamalı" olarak görüyorum.