Analyse approfondie de vuex
- Un, État
- 二 、 Vuex_Getter
- Trois, Vuex_Mutation
-
- 1. Soumettez la mutation dans le composant
- 2. Soumettez la charge utile (Payload)
- 3. Méthode de soumission du style d'objet
- 4. Utilisez des constantes au lieu des types d'événement Mutation
- 5. La mutation est soumise aux règles de réponse de Vue
- 6. Traitement des formulaires
- 7. La mutation doit être une fonction synchrone
- 8. Mode strict
- Quatre, Vuex_Action
- 五 、 Vuex_Module
Un, État
Vuex est l'outil de gestion d'état de Vue, afin de réaliser plus facilement l'état partagé de plusieurs composants.
1. Installation
npm install vuex --save
2. Utilisez
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
}
})
new Vue({
store,
})
3. État
Dans une seule arborescence d'états, l'utilisation d'un objet contient tous les états au niveau de l'application.
1. Obtenez l'état de Vuex dans le composant Vue
Grâce à l'option store, Vuex fournit un mécanisme pour "injecter" l'état du composant suiveur dans chaque composant enfant (appel Vue.use (Vuex)).
En enregistrant l'option store dans l'instance racine, l'instance store sera injectée dans tous les sous-composants sous le composant racine, et les sous-composants seront accessibles via. $ Store.
<div class="home">
{
{ $store.state.count }}
</div>
2. fonction d'assistance mapState
Lorsqu'un composant doit obtenir plusieurs états, déclarer ces états comme des propriétés calculées sera quelque peu répétitif et redondant. Pour résoudre ce problème, nous pouvons utiliser la fonction d'assistance mapState pour nous aider à générer des attributs calculés:
import {
mapState } from 'vuex';
computed: {
...mapState(['count']),
},
Utilisez des noms différents:
computed: {
...mapState({
storeCount: state => state.count,
// 简写
storeCount: 'count', // 等同于 state => state.count
}),
},
二 、 Vuex_Getter
Les propriétés calculées du magasin. La valeur de retour du getter sera mise en cache en fonction de ses dépendances et ne sera recalculée que lorsque sa valeur de dépendance change.
Getter reçoit l'état comme premier paramètre et obtient comme deuxième paramètre.
getters: {
doubleCount (state) {
return state.count * 2;
}
}
1. Accès via les attributs
Getter sera exposé en tant qu'objet store.getters:this.$store.getters.doubleCount
2. Accès par méthode
Vous pouvez également laisser le getter renvoyer une fonction pour passer des paramètres au getter
getters: {
addCount: state => num => state.count + num;
}
this.$store.addCount(3);
3. fonction d'assistance mapGetters
import {
mapsGetters } from 'vuex';
export default {
computed: {
...mapGetters([
'doubleCount',
'addCount',
])
}
}
Si vous souhaitez donner un autre nom à une propriété getter, utilisez le formulaire objet:
mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
storeDoubleCount: 'doubleCount'
})
Trois, Vuex_Mutation
La seule façon de changer l'état dans le magasin Vuex est de soumettre une mutation.
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
Vous ne pouvez pas appeler directement un gestionnaire de mutation. Cette option ressemble plus à l'enregistrement d'événement: "Lorsqu'une increment
mutation de type est déclenchée , appelez la fonction secondaire.":
this.$store.commit('increment');
1. Soumettez la mutation dans le composant
Sauf que dans l'assemblage this.$store.commit('xxx')
pour soumettre la mutation, il peut également être utilisé les helpers de mapMutations:
import {
mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
2. Soumettez la charge utile (Payload)
Vous pouvez passer des paramètres supplémentaires à store.commit, à savoir la charge utile de la mutation:
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
Dans la plupart des cas, la charge utile doit être un objet, afin de pouvoir contenir plusieurs champs et la mutation enregistrée sera plus lisible:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {
amount: 10
})
3. Méthode de soumission du style d'objet
Une autre façon de soumettre une mutation consiste à utiliser directement l'objet qui contient l'attribut type:
store.commit({
type: 'increment',
amount: 10
})
Lors de l'utilisation de la méthode de soumission de style objet, l'objet entier est passé à la fonction de mutation en tant que charge utile, de sorte que le gestionnaire reste inchangé:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
4. Utilisez des constantes au lieu des types d'événement Mutation
Le fait de placer ces constantes dans un fichier séparé permet à vos collaborateurs de code de voir en un coup d'œil les mutations contenues dans l'ensemble de l'application:
// mutation-types.js
export const COUNT_INCREMENT = 'COUNT_INCREMENT'
// store.js
import Vuex from 'vuex'
import {
COUNT_INCREMENT } from './mutation-types'
const store = new Vuex.Store({
state: {
... },
mutations: {
[COUNT_INCREMENT] (state) {
// ...
}
}
})
C'est à vous d'utiliser des constantes, ce qui peut être utile dans les grands projets qui nécessitent une collaboration multi-personnes.
5. La mutation est soumise aux règles de réponse de Vue
Étant donné que l'état dans le magasin Vuex est réactif, lorsque nous modifions l'état, le composant Vue qui surveille l'état sera également mis à jour automatiquement. Cela signifie également que les mutations dans Vuex doivent également suivre certaines précautions comme avec Vue:
- Il est préférable d'initialiser à l'avance tous les attributs requis dans votre boutique.
- Lorsque vous devez ajouter de nouvelles propriétés à l'objet, vous devez
- Utilisez Vue.set (obj, 'newProp', 123), ou
- Remplacez les anciens objets par de nouveaux objets. Par exemple, en utilisant l'opérateur d'expansion d'objet, nous pouvons écrire:
state.obj = { ...state.obj, newProp: 123 }
6. Traitement des formulaires
Lors de l'utilisation de v-model sur l'état de Vuex, Vue générera une erreur car il changera directement la valeur de l'état.
Si vous souhaitez utiliser la fonction de données bidirectionnelle, vous devez simuler vous-même un modèle en v:: value = "msg" @ input = "updateMsg".
1. Propriétés de calcul de liaison bidirectionnelle
L'approche ci-dessus est beaucoup plus lourde que le v-model lui-même, nous pouvons donc également utiliser le setter de la propriété calculée pour obtenir une liaison bidirectionnelle:
<input v-model="msg">
computed: {
msg: {
get () {
return this.$store.state.obj.msg;
},
set (value) {
this.$store.commit(UPDATE_MSG, {
value });
}
}
}
7. La mutation doit être une fonction synchrone
N'oubliez pas que la mutation doit être une fonction synchrone . Pourquoi?
mutations: {
[COUNT_INCREMENT] (state) {
setTimeout(() => {
state.count ++;
}, 1000)
},
}
En exécutant le code supérieur, nous verrons que l'opération de changement d'état est exécutée dans la fonction de rappel, ce qui rendra notre code difficile à déboguer dans devtools: lorsque la mutation est déclenchée, la fonction de rappel n'a pas encore été appelée, devtools ne sait pas Lorsque la fonction de rappel est effectivement appelée, toutes les modifications d'état effectuées dans la fonction de rappel sont introuvables.
8. Mode strict
Pour activer le mode strict, il suffit de passer strict: true lors de la création du magasin:
const store = new Vuex.Store({
// ...
strict: true
})
En mode strict, chaque fois qu'un changement d'état se produit et n'est pas provoqué par la fonction de mutation, une erreur est générée. Cela garantit que tous les changements d'état peuvent être suivis par des outils de débogage.
1. Environnement de développement et environnement de version
N'activez pas le mode strict dans l'environnement de publication! Le mode strict surveillera en profondeur l'arborescence des états pour détecter les changements d'état non conformes. Assurez-vous de désactiver le mode strict dans l'environnement de version pour éviter toute perte de performances.
const store = new Vuex.Store({
// ...
strict: process.env.NODE_ENV !== 'production'
})
Quatre, Vuex_Action
L'action est similaire à la mutation, la différence est:
- Action soumet une mutation au lieu de changer directement l'état.
- L'action peut contenir n'importe quelle opération asynchrone
La fonction Action accepte un objet de contexte avec les mêmes méthodes et propriétés que l'instance de magasin, vous pouvez donc appeler context.commit pour soumettre une mutation, ou obtenir l'état et les getters via context.state et context.getters:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
1. Distribuer l'action
store.dispatch('increment')
Bien que similaires à la mutation, les opérations asynchrones peuvent être effectuées en action, mais pas en mutation! ! !
actions: {
incrementAsync ({
commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
2. Action combinée
L'action est généralement asynchrone, alors comment savoir quand l'action se termine?
actions: {
actionA ({
commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
store.dispatch('actionA').then(() => {
// ...
})
Mode de gestion 3.Vuex
五 、 Vuex_Module
En raison de l'utilisation d'un seul arbre d'état, tous les états de l'application seront concentrés dans un objet relativement grand. Lorsque l'application devient très complexe, l'objet de stockage peut devenir assez gonflé.
Pour résoudre les problèmes ci-dessus, Vuex nous permet de diviser le magasin en modules. Chaque module a son propre état, mutation, action et getter.
modules: {
a,
b
}
- 获取 état : ceci. $ Store.state.moduleName.xxx
- 获取 getter : ceci. $ Store.getters.xxx
- Soumettre la mutation: this. $ Store.commit ('xxx');
- Action de distribution: this. $ Store.dispatch ('xxx');
- Vous pouvez obtenir des getters, des mutations et des actions via mapXXX, mais vous ne pouvez pas obtenir l'état. Si vous souhaitez obtenir l'état de cette manière, vous devez ajouter un espace de noms.
1. Espace de noms
Vous pouvez en faire un module avec des espaces de noms en ajoutant namespaced: true.
- 获取 état : ceci. $ Store.state.moduleName.xxx
- 获取 getter : this. $ Store. ['ModuleName / getters']. Xxx
- 提交 mutation : this. $ Store.commit ('moduleName / xxx');
- 分发 action : this. $ Store.dispatch ('moduleName / xxx');
- Vous pouvez obtenir l'état, les getters, les mutations et les actions via mapXXX.
2. L'état local du module
Pour la mutation et le getter à l'intérieur du module, le premier paramètre reçu est l'objet d'état local du module.
De même, pour les actions à l'intérieur du module, l'état local est exposé via context.state et l'état du nœud racine est context.rootState.
Pour le getter à l'intérieur du module, l'état du nœud racine sera exposé comme troisième paramètre.