Site icon Blog ARC Optimizer

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 de Counter.vue ajoutez ce code:

 méthodes: {
  incrément: function () {
    this.count ++;
  },
  décrémentation: function () {
    this.count--;
  },
  incrementIfOdd: function () {
    if (this.parity === 'impair') {
      this.increment ();
    }
  },
  incrementAsync: function () {
    setTimeout (() => {
      this.increment ()
    }, 1000)
  }
}
Les deux premières fonctions, incrémenter et décrémenter sont, espérons-le, explicites. La fonction incrementIfOdd ne s'exécute que si la valeur de count est un nombre impair, alors que incrementAsync est une fonction asynchrone qui effectue un incrément après une seconde. Pour accéder à ces nouvelles méthodes à partir du modèle, nous devrons définir des boutons. Insérez ce qui suit après le code modèle qui fournit le nombre et la parité:




Une fois que vous avez enregistré, le navigateur devrait s'actualiser automatiquement. Cliquez sur tous les boutons pour vous assurer que tout fonctionne comme prévu.

Voir le stylo Vue Counter Using Local State de SitePoint ( @SitePoint ) sur CodePen . ] L'exemple de compteur est maintenant terminé. Passons maintenant aux principes fondamentaux de Vuex avant d'examiner comment réécrire le compteur pour les implémenter.

Fonctionnement de Vuex

Avant de passer en revue la mise en œuvre pratique, il est préférable d'acquérir une compréhension de base de la façon dont Vuex le code est organisé. Si vous connaissez des frameworks similaires tels que Redux, vous ne devriez pas trouver quelque chose de trop surprenant ici. Si vous n'avez encore jamais utilisé de framework de gestion d'état basé sur Flux, portez une attention particulière.

Le magasin Vuex

Le magasin fournit un référentiel centralisé des états partagés dans les applications Vue. Voici à quoi il ressemble dans sa forme la plus élémentaire:
 // src / store / index.js

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

Vue.use (Vuex)

exporter par défaut le nouveau Vuex.Store ({
  Etat: {
    // met les variables et les collections ici
  },
  mutations: {
    // met des fonctions synchrones pour changer d'état, par ex. ajouter, éditer, supprimer
  },
  actes: {
    // place des fonctions asynchrones pouvant appeler une ou plusieurs fonctions de mutation
  }
})
Après avoir défini votre magasin, vous devez l'injecter dans votre application Vue.js comme ceci:
 // src / main.js
importer un magasin à partir de './store'

nouveau Vue ({
  le magasin,
  rendre: h => h (App)
}). $ mount ('# app')
Ceci rendra l'instance de magasin injectée disponible pour chaque composant de notre application sous le nom this. $ Store .

Working with State

Aussi appelé arbre à état unique il s'agit simplement d'un objet contenant toutes les données de l'application frontale. Tout comme Redux, Vuex fonctionne avec un seul magasin. Les données d'application sont organisées dans une structure arborescente. Sa construction est assez simple. Voici un exemple:
 déclarez: {
  produits: [],
  compte: 5,
  logsInUser: {
    nom: 'John',
    rôle: 'Admin'
  }
}
Nous avons ici produits que nous avons initialisés avec un tableau vide, et count qui est initialisé avec la valeur 5. Nous avons également LOGINU , qui est un objet littéral JavaScript contenant plusieurs champs. Les propriétés d'état peuvent contenir n'importe quel type de données valide, qu'il s'agisse de booléens, de tableaux ou d'autres objets. Il existe plusieurs façons d'afficher l'état dans nos vues. Nous pouvons référencer le magasin directement dans nos modèles en utilisant $ store :

Ou nous pouvons retourner un état de magasin à partir d'une propriété calculée :



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 . 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
Quitter la version mobile