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:
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:
Vuex Counter
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:
Cliqué {{count}} fois! Le nombre est égal à {{parity}}.
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:
Bienvenue, {{logInUser.name}}.
Le nombre est {{count}}.
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èscontext.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:
Vuex
a été installé en tant que dépendance de paquet. Vérifiez votrepackage.json
pour le confirmer.- Un fichier
store.js
a été créé et inséré dans votre application Vue.js viamain.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 . Nous allons basculer l'état et les fonctions locales vers celles nouvellement créées dans le magasin Vuex:
import {mapState mapGetters, mapActions} de 'vuex'
défaut d'exportation {
nom: 'Counter',
calculé: {
... mapState ([
'count'
]),
... carteGetters ([
'parity'
])
},
méthodes: mapActions ([
'increment',
'decrement',
'incrementIfOdd',
'incrementAsync'
])
}
Le code du modèle devrait rester le même, car nous nous en tenons aux noms de variable et de fonction précédents. Voyez à quel point le code est maintenant plus propre.
Si vous ne souhaitez pas utiliser les aides de carte d'état et d'accesseur, vous pouvez accéder aux données de la boutique directement à partir de votre modèle, comme suit:
Cliquez sur {{$ store.state. .count}} fois! Le compte est {{$ store.getters.parity}}.
Après avoir enregistré vos modifications, veillez à tester votre application. Du point de vue de l'utilisateur final, l'application de compteur doit fonctionner exactement comme avant. La seule différence est que le compteur fonctionne à partir d'un magasin Vuex.
Voir le stylo Vue Counter utilisant Vuex de SitePoint ( @SitePoint ) sur CodePen .
Conclusion
Dans cet article, nous avons examiné ce qu'est Vuex, quel problème il résout, comment l'installer et ses concepts de base. Nous avons ensuite appliqué ces concepts pour refactoriser notre application de comptoir afin qu'elle fonctionne avec Vuex. Espérons que cette introduction vous aidera à implémenter Vuex dans vos propres projets.
Il convient également de noter que l’utilisation de Vuex dans une application aussi simple est une surabondance totale. Cependant, dans un autre article - Créer une application de liste de magasinage avec Vue, Vuex et Bootstrap Vue - Je construirai une application plus complexe pour illustrer un scénario plus réaliste, ainsi que certains des plus avancés de Vuex.
Source link