Analyse approfondie de vuex

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 incrementmutation 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

Insérez la description de l'image ici

五 、 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.

Je suppose que tu aimes

Origine blog.csdn.net/xun__xing/article/details/108580007
conseillé
Classement