Fermer

juin 18, 2019

un guide du débutant –


Dans les applications à une page, le concept de état concerne toute donnée susceptible de changer. Un exemple d'état peut être les détails d'un utilisateur connecté ou les données extraites d'une API.

La gestion de l'état dans des applications d'une page peut être un processus délicat. Lorsqu'une application devient de plus en plus vaste et complexe, vous commencez à être confronté à des situations dans lesquelles un élément d'état donné doit être utilisé dans plusieurs composants, ou vous vous retrouvez en train de passer d'un état à un autre sans en avoir besoin, simplement doit être. Ceci est également connu sous le nom de «forage de prop» et peut conduire à un code difficile à manier.

Vuex est la solution officielle de gestion de l'état pour Vue. Il fonctionne avec un magasin central pour l'état partagé et fournit des méthodes permettant à tout composant de votre application d'accéder à cet état. En résumé, Vuex garantit la cohérence de vos vues avec les données de votre application, quelle que soit la fonction qui déclenche une modification des données de votre application.

Dans cet article, je vais vous présenter un aperçu de haut niveau de Vuex et vous montrer comment l'implémenter.

Voulez-vous apprendre Vue.js de fond en comble? Obtenez une collection complète de livres Vue couvrant les bases, les projets, les astuces, les outils et plus avec SitePoint Premium. Inscrivez-vous maintenant pour seulement 9 dollars par mois .

Prenons un exemple concret pour illustrer le problème résolu par Vuex.

Lorsque vous vous rendez sur un site d'achat, vous disposez généralement d'une liste. de produits. Chaque produit comporte un bouton Ajouter au panier et parfois une étiquette Articles restant indiquant le stock actuel ou le nombre maximum d'articles pouvant être commandés pour le produit spécifié. Chaque fois qu'un produit est acheté, le stock actuel de ce produit est réduit. Lorsque cela se produit, l'étiquette Éléments restants doit être mise à jour avec le chiffre correct. Lorsque le niveau des stocks du produit atteint 0, l’étiquette doit se lire En rupture de stock . De plus, le bouton Ajouter au panier doit être désactivé ou masqué pour empêcher les clients de commander des produits qui ne sont pas en stock.

Demandez-vous maintenant comment vous allez implémenter cette logique. Cela peut être plus compliqué que vous ne le pensez. Et laissez-moi lancer une balle courbe. Vous aurez besoin d'une autre fonction pour mettre à jour les enregistrements de stock lorsque de nouveaux stocks entreront. Lorsque le stock du produit épuisé est mis à jour, l'étiquette Articles restant et le bouton Ajouter au panier doivent être mis à jour. instantanément pour refléter le nouvel état du stock.

En fonction de vos prouesses en matière de programmation, votre solution peut commencer à ressembler un peu à des spaghettis. Imaginons maintenant que votre responsable vous demande de développer une API permettant aux sites tiers de vendre les produits directement à partir de l’entrepôt. L’API doit garantir que le site Web principal des achats reste en phase avec les niveaux de stock des produits. À ce stade, vous avez envie de tirer les cheveux en arrière et de demander pourquoi on ne vous a pas demandé de le mettre en œuvre plus tôt. Vous avez le sentiment que tout votre travail acharné a été perdu, car vous devrez retravailler complètement votre code pour faire face à cette nouvelle exigence.

C’est là qu’une bibliothèque de modèles de gestion d’État peut vous éviter de tels maux de tête. Cela vous aidera à organiser le code qui traite vos données frontales de manière à faciliter l'ajout de nouvelles exigences.

Conditions préalables

Avant de commencer, je suppose que vous:

  • avez des connaissances de base. Vue.js
  • connaissent ES6 et ES7 fonctionnalités linguistiques

Vous aurez également besoin d'une version récente de Node.js qui n'est pas plus ancienne. que la version 6.0. Au moment de la rédaction, Node.js v10.13.0 (LTS) et npm version 6.4.1 sont les plus récents. Si vous ne possédez pas déjà une version appropriée de Node installée sur votre système, je vous recommande d'utiliser un gestionnaire de version [1945921].

Enfin, vous devriez disposer de la version la plus récente du Vue CLI [ installé:

 npm install -g @ vue / cli

Construire un compteur en utilisant l’état local

Dans cette section, nous allons construire un compteur simple qui garde une trace de son état localement. Une fois que nous aurons terminé, je passerai en revue les concepts fondamentaux de Vuex avant de voir comment réécrire l'application de compteur pour qu'elle utilise la solution de gestion d'état officielle de Vue.

Mise en place

Générons un nouveau projet à l'aide de la CLI:

 vue create vuex-counter

Un assistant s'ouvrira pour vous guider tout au long de la création du projet. Sélectionnez Sélectionnez manuellement les fonctionnalités et assurez-vous d'installer Installateur Vuex.

Ensuite, accédez au nouveau répertoire et au dossier src / components renommez le HelloWorld.vue. à Counter.vue :

 cd vuex-counter
mv src / components / HelloWorld.vue src / components / Counter.vue

Enfin, ouvrez src / App.vue et remplacez le code existant par ce qui suit:

  

Vous pouvez laisser les styles tels quels.

Créer le compteur

Commençons par initialiser un compte et l’afficher sur la page. Nous informerons également l'utilisateur si le nombre est actuellement pair ou impair. Ouvrez src / components / Counter.vue et remplacez le code par ce qui suit:

  

Comme vous pouvez le voir, nous avons une variable d'état appelée count et une fonction calculée appelée parity qui renvoie la chaîne même ou odd en fonction du nombre de est un nombre impair ou pair.

Pour voir ce que nous avons jusqu'à présent, démarrez l'application depuis le dossier racine en exécutant npm run serve et naviguez jusqu'à http: // localhost: 8080 .

N'hésitez pas à modifier la valeur du compteur pour indiquer que le résultat correct est correct pour compteur et . la parité est affichée. Lorsque vous êtes satisfait, assurez-vous de le réinitialiser à 0 avant de passer à l'étape suivante.

Incrémenter et décrémenter

Juste après la propriété calculée dans la section

Les magasins Vuex étant réactifs, chaque fois que la valeur de $ store.state.count change, la vue change également. Tout cela se passe dans les coulisses, ce qui rend votre code plus simple et plus propre.

The mapState Helper

Supposons maintenant que vous souhaitiez afficher plusieurs états dans vos vues. La déclaration d'une longue liste de propriétés calculées peut devenir prolixe. Vuex fournit donc un assistant mapState . Ceci peut être utilisé pour générer facilement plusieurs propriétés calculées. Voici un exemple:

  

Voici une alternative encore plus simple où nous pouvons passer un tableau de chaînes à la fonction d'assistance mapState :

 export default {
  calculé: mapState ([
    'count', 'loggedInUser'
  ])
}

Cette version du code et celle qui la précède font exactement la même chose. Notez que mapState renvoie un objet. Si vous souhaitez l'utiliser avec d'autres propriétés calculées, vous pouvez utiliser l'opérateur étendu . Voici comment:

 a calculé: {
  ... mapState ([
    'count', 'loggedInUser'
  ]),
  parité: function () {
    renvoyer this.count% 2 === 0? 'même bizarre'
  }
}

Getters

Dans un magasin Vuex, les getters sont l’équivalent des propriétés calculées de Vue. Ils vous permettent de créer un état dérivé pouvant être partagé entre différents composants. Voici un exemple rapide:

 getters: {
  depletedProducts: state => {
    return state.products.filter (product => product.stock <= 0)
  }
}

Les résultats des gestionnaires getter (accessibles en tant que propriétés) sont mis en cache et peuvent être appelés autant de fois que vous le souhaitez. Ils réagissent également aux changements d’état. En d'autres termes, si l'état dont il dépend dépend des modifications, la fonction getter est automatiquement exécutée et le nouveau résultat est mis en cache. Tout composant ayant accédé à un gestionnaire getter sera mis à jour instantanément. Voici comment accéder à un gestionnaire getter à partir d'un composant:

 calculé: {
  depletedProducts () {
    renvoyer cette. $ store.getters.depletedProducts;
  }
}

Le mapGetters Helper

Vous pouvez simplifier le code getters en utilisant le assistant MapGetters :

 import {mapGetters} de 'vuex'

défaut d'exportation {
  // ..
  calculé: {
    ... carteGetters ([
      'depletedProducts',
      'anotherGetter'
    ])
  }
}

Il est possible de passer des arguments à un gestionnaire getter en renvoyant une fonction. Ceci est utile si vous souhaitez effectuer une requête dans le getter :

: {
  getProductById: state => id => {
    return state.products.find (product => product.id === id);
  }
}

store.getters.getProductById (5)

Notez que chaque fois qu'un gestionnaire getter est accédé via une méthode, il sera toujours exécuté et le résultat ne sera pas mis en cache.

Compare:

 // notation de propriété, résultat mis en cache
store.getters.depletedProducts

// notation de la méthode, résultat non mis en cache
store.getters.getProductById (5)

Modification d'état avec mutations

Un aspect important de l'architecture Vuex est que les composants ne modifient jamais l'état directement. Cela peut entraîner des bugs étranges et des incohérences dans l'état de l'application.

Au lieu de cela, le moyen de changer d'état dans un magasin Vuex consiste à effectuer une mutation . Pour ceux d'entre vous qui connaissent bien Redux, ils ressemblent à réducteurs .

Voici un exemple de mutation qui augmente la valeur du nombre stockée dans l'état . :

 exporte par défaut le nouveau Vuex.Store ({
  Etat:{
    compte: 1
  },
  mutations: {
    incrément (état) {
      state.count ++
    }
  }
})

Vous ne pouvez pas appeler directement un gestionnaire de mutation. Au lieu de cela, vous en déclenchez une en «commettant une mutation» comme ceci:

 méthodes: {
  updateCount () {
    this. $ store.commit ('incrémentation');
  }
}

Vous pouvez également transmettre des paramètres à une mutation:

 // store.js
mutations: {
  incrementBy (state, n) {
    state.count + = n;
  }
}
 // composant
updateCount () {
  ceci. $ store.commit ('incrementBy', 25);
}

Dans l’exemple ci-dessus, nous transmettons à la mutation un entier lui permettant d’augmenter le nombre. Vous pouvez également passer un objet en tant que paramètre. De cette façon, vous pouvez facilement inclure plusieurs champs sans surcharger votre gestionnaire de mutation:

 // store.js
mutations: {
  incrementBy (état, charge utile) {
    state.count + = payload.amount;
  }
}
 // composant
updateCount () {
  this. $ store.commit ('incrementBy', {montant: 25});
}

Vous pouvez également effectuer un commit de style objet, ressemblant à ceci:

 store.commit ({
  type: 'incrementBy',
  montant: 25
})

Le gestionnaire de mutations restera le même.

The mapMutations Helper

Semblable à similaire à mapState et vous pouvez également utiliser le mapMutations aide à réduire le passe-partout pour vos gestionnaires de mutations:

 import {mapMutations} de 'vuex'

défaut d'exportation {
  méthodes: {
    ... mapMutations ([
      'increment', // maps to this.increment()
      'incrementBy' // maps to this.incrementBy(amount)
    ])
  }
}

Enfin, les gestionnaires de mutations doivent être synchrones. Vous pouvez essayer d'écrire une fonction de mutation asynchrone, mais vous découvrirez plus tard qu'elle cause des complications inutiles. Passons aux actions.

Actions

Les actions sont des fonctions qui ne changent pas l’Etat elles-mêmes. Au lieu de cela, ils commettent des mutations après avoir exécuté une logique (qui est souvent asynchrone). Voici un exemple simple d’action:

 // ..
actes: {
  incrément (contexte) {
    context.commit ('increment');
  }
}

Les gestionnaires d'action reçoivent comme premier argument un objet de contexte ce qui nous permet d'accéder aux propriétés et aux méthodes du magasin. Par exemple:

  • context.commit : commettre une mutation
  • context.state : état d'accès
  • context.getters : accès aux getters

Vous pouvez également utiliser argument détruisant pour extraire les attributs de magasin dont vous avez besoin pour votre code. Par exemple:

 actions: {
  incrémenter ({commit}) {
    commit ('increment');
  }
}

Comme mentionné ci-dessus, les actions peuvent être asynchrones. Voici un exemple:

 actions: {
  incrementAsync: async ({commit}) => {
    return wait setTimeout (() => {commit ('increment')}, 1000);
  }
}

Dans cet exemple, la mutation est engagée au bout de 1 000 millisecondes.

Comme les mutations, les gestionnaires d'action ne sont pas appelés directement, mais via une méthode dédiée dispatch sur le magasin, comme suit: [19659040] store.dispatch ('incrementAsync')

// envoi avec charge utile
store.dispatch ('incrementBy', {montant: 25})

// envoi avec objet
store.dispatch ({
  type: 'incrementBy',
  montant: 25
})

Vous pouvez envoyer une action dans un composant tel que:

 this. $ Store.dispatch ('increment')

L'assistant mapActions

Vous pouvez également utiliser l'assistant mapActions pour affecter des gestionnaires d'actions à des méthodes locales:

 import {mapActions} de 'vuex '

défaut d'exportation {
  // ..
  méthodes: {
    ... mapActions ([
      'incrementBy', // maps this.increment(amount) to this.$store.dispatch(increment)
      'incrementAsync', // maps this.incrementAsync() to this.$store.dispatch(incrementAsync)
      add: 'increment' // maps this.add() to this.$store.dispatch(increment)
    ])
  }
}

Reconstruire une application de compteur avec Vuex

Maintenant que nous avons examiné les concepts de base de Vuex, il est temps de mettre en œuvre ce que nous avons appris et de réécrire notre compteur pour utiliser la solution de gestion d'état officielle de Vue. .

Si vous avez envie de relever un défi, vous voudrez peut-être le faire vous-même avant de lire…

Lorsque nous avons généré notre projet avec Vue CLI nous avons sélectionné Vuex comme l'une des caractéristiques. Quelques événements se sont produits:

  1. Vuex a été installé en tant que dépendance de paquet. Vérifiez votre package.json pour le confirmer.
  2. Un fichier store.js a été créé et inséré dans votre application Vue.js via main.js .

Pour convertir notre application de compteur «local state» en une application Vuex, ouvrez le src / store.js et mettez à jour le code comme suit:

 import Vue Vue de 'vue'
importer Vuex depuis 'vuex'

Vue.use (Vuex)

exporter par défaut le nouveau Vuex.Store ({
  Etat: {
    compte: 0
  },
  getters: {
    parité: state => state.count% 2 === 0? 'même bizarre'
  },
  mutations: {
    incrément (état) {
      state.count ++;
    },
    décrémentation (état) {
      state.count--;
    }
  },
  actes: {
    increment: ({commit}) => commit ('increment'),
    décrémenter: ({commit}) => commit ('décrémenter'),
    incrementIfOdd: ({commit, getters}) => getters.parity === 'impair'? commit ('increment'): false,
    incrementAsync: ({commit}) => {
      setTimeout (() => {commit ('increment')}, 1000);
    }
  }
});

Nous pouvons voir ici comment un magasin Vuex complet est structuré dans la pratique. Veuillez revenir en arrière sur la partie théorique de cet article si quelque chose ici ne vous semble pas clair.

Ensuite, mettez à jour le composant src / components / Counter.vue en remplaçant le code existant dans le bloc

Source link