Les applications frontales, en particulier les plus complexes, doivent traiter un grand nombre de données. Les programmeurs introduisent divers modèles de conception pour rendre leurs projets lisibles et faciles à maintenir. Dans la plupart des scénarios courants de traitement d'un MVC, nous voulons séparer les données des parties visuelles de l'application.
C'est la raison pour laquelle magasin est devenu si utile. C'est à vous de décider si vous utilisez React + Redux ou Vue + Vuex - l'objectif principal est le même, à savoir en gardant vos données structurées, accessibles et sûres à la fois.
Dans cet article, je vais vous montrer quelques exemples de la manière de garder votre magasin Vuex propre et efficace.
Avant de commencer, supposons que.. :
- vous avez une certaine expérience de la modernité JavaScript,
- vous savez ce qu'est Vue et comment l'utiliser accessoires, calculée, etc,
- vous connaissez Vuex (actions, mutations, etc.) et souhaitez améliorer vos applications.
VuexComme la majorité des pays de l'Union européenne, l'Union européenne est un acteur majeur de l'économie mondiale. Projets Vueest assez bien documenté et vous pouvez trouver de nombreuses astuces utiles dans les documents officiels. Nous avons extrait quelques informations essentielles pour vous.
La mise en œuvre d'un magasin Vuex de base se présente comme suit :
// main.js
import Vue de "vue
import Vuex from 'vuex'
import App from "./App" ;
Vue.use(Vuex)
const store = new Vuex.Store((
état : (
données : null ;
),
actions : (
someAction : (( commit ), data) (
commit("SOME_MUTATION", données) ;
)
),
mutations : (
SOME_MUTATION (état, données) (
state.data = data ;
)
))
)) ;
nouveau Vue((
el : "#app",
render : h => h(App),
store
)) ;
Habituellement, lorsque votre application devient plus grande, vous devez appliquer le routage, certaines directives globales, des plugins, etc. Cela rend l'application main.js
beaucoup plus long et difficile à lire. C'est une bonne pratique que de conserver le magasin dans un fichier externe, comme ici :
// store.js
import Vue de "vue
import Vuex from 'vuex'
Vue.use(Vuex) ;
const state = (
data : null ;
) ;
const actions = (
someAction : (( commit ), data) (
commit("SOME_MUTATION", data) ;
)
) ;
const mutations = (
SOME_MUTATION (état, données) (
state.data = data ;
)
) ;
export default new Vuex.Store((
état,
actions,
mutations
)) ;
1. Les modules
Que faire lorsque le store.js
devient énorme et difficile à travailler ? En fait, il existe une fonction Vuex très intéressante - modules. Ils sont destinés à diviser vos données en fichiers distincts.
Imaginez que vous travaillez sur une application d'entreprise, dans laquelle vous disposez de quelques domaines de données, par exemple :
- l'utilisateur (qui gère toutes les autorisations et permissions),
- paramètres d'acheminement (gestion des paramètres globaux avant les requêtes à l'API),
- les ventes (pour votre composant SalesMegaChart visible dans un contexte mensuel/trimestriel/annuel),
- commandes (visible après avoir cliqué sur la barre SalesMegaChart).
...et peut-être d'autres encore. Vous avez maintenant de sérieuses raisons d'introduire un peu de modularité dans votre magasin.
Tout d'abord, déplacez le store.js
dans un fichier magasin/
et le renommer index.js
. En option, si vous souhaitez que tout soit regroupé dans des modules, supprimez État, actions et mutations du fichier principal.
// store/index.js
import Vue de "vue
import Vuex de 'vue'
Vue.use(Vuex) ;
export default new Vuex.Store((
modules : (
// les modules iront ici
)
)) ;
Ensuite, à côté du fichier `store/index.js`, créez le premier module - `store/user.js`.
import ApiService from '../services/api.service' ;
const state = (
loggedIn : false,
loginError : null,
user : null
) ;
const actions = (
login : async (( commit ), data) (
try (
const response = await ApiService.post('/login', data) ;
const ( user ) = response.data ;
COMMIT("SAVE_USER", user) ;
COMMIT("LOGIN_SUCCESS") ;
) catch (error) (
commit("LOGIN_ERROR", erreur) ;
)
)
) ;
constantes mutations = (
SAVE_USER (state, user) (
state.user = user ;
),
LOGIN_SUCCESS (état) (
state.loggedIn = true ;
),
LOGIN_ERROR (state, error) (
state.loginError = error ;
state.loggedIn = false ;
)
) ;
export const user (
state,
actions,
mutations
)
Et maintenant, chargez le module ready dans le fichier principal `store/index.js` :
import Vue from 'vue'
import Vuex from 'vue'
import ( user ) from './user' ;
Vue.use(Vuex) ;
export default new Vuex.Store((
modules : (
utilisateur
)
)) ;
Félicitations ! Vous disposez à présent d'une implémentation de magasin très attrayante. Vous pouvez également accéder aux données à partir du composant (par ex, UserProfile.vue
) comme suit :
<template>
<div class="user-profile">
<h2>(( nom.utilisateur )) !</h2>
<!-- component template goes here -->
</div>
</template>
<script> import ( mapActions ) from 'Vuex';
export default (
name: 'UserProfile',
computed: mapState((
user: state => state.user
// user: 'user' <-- alternative syntax
))
)
</script>
2. Espaces de noms
Maintenant que vous savez comment utiliser les modules, vous devez également vous familiariser avec les fonctions suivantes du Vuex espacement des noms. A l'étape précédente, nous avons créé le fichier store/user.js
avec le fichier utilisateur module.
La structure de données définie dans le user.js
est accessible à partir des composants, mais vous pouvez constater que tous les fichiers utilisateur Les données sont directement envoyées au système global de gestion de l'information. État
contexte, comme ici :
computed : mapState((
user : state => state.user
// user : 'user' <-- alternative way
))
Lorsque vous définissez d'autres modules, vous risquez de ne plus savoir quel objet provient de quel module. Vous devriez alors utiliser des modules à espace de noms et les définir de cette manière :
export const user (
namespaced : true, // <-- namespacing !
state,
actions,
mutations
)
Désormais, tous vos utilisateur données (État
variable de store/user.js
) sera traité dans le cadre de la état.utilisateur
référence :
computed : mapState((
user : state => state.user.user
// user : 'user/user' <-- alternative way
))
Quelques étapes plus tard, vous pouvez obtenir pour le composant quelque chose comme ceci :
import ( mapActions ) from 'Vuex' ;
export default (
nom : "Tableau de bord",
calculé : mapState((
sales : 'sales/data',
orders : 'orders/data',
sortBy : 'commandes/sortBy',
loggedIn : 'user/loggedIn'
)),
methods : mapActions((
logout : 'user/logout',
loadSales : "sales/load",
loadOrders : 'orders/load'
)),
created() (
si (this.loggedIn) (
loadSales() ;
loadOrders() ;
)
)
)
Bravo ! Si frais, si propre... Mais ne vous inquiétez pas, le remaniement ne s'arrête jamais. Prêt pour les prochaines étapes ?
3. Communication entre les modules
Dans la première étape, je vous ai montré une action dans le utilisateur module :
const actions = (
login : async (( commit ), data) (
try (
const response = await ApiService.post('/login', data) ;
const ( user ) = response.data ;
COMMIT("SAVE_USER", user) ;
COMMIT("LOGIN_SUCCESS") ;
) catch (error) (
commit("LOGIN_ERROR", erreur) ;
)
)
) ;
En cas d'échec, nous ajoutons l'erreur de connexion à notre boutique - quelle est la prochaine étape ?
Plusieurs possibilités s'offrent à nous et le choix dépend de l'option qui convient le mieux à vos besoins. La méthode la plus simple consiste à utiliser le v-if
grâce à laquelle un message d'erreur peut être affiché en cas d'erreur dans votre boutique.
<template>
<div class="dashboard">
<!-- dashboard component template -->
<div
v-if="error"
class="error-message"
> (( message.d'erreur )) </div>
</div>
</template>
<script> import ( mapActions ) from 'Vuex';
export default (
name: 'Dashboard',
computed: mapState((
error: "user/loginError"
))
)
</script>
Imaginons à nouveau que vous disposiez de nombreux modules et que chacun d'entre eux try/catch
génère une nouvelle erreur dans votre magasin. Il est évident que vous allez abuser de la règle DRY de cette manière.
Comment pouvez-vous rendre vos processus de traitement des erreurs plus génériques ?
Définissons le commun et d'y intégrer une logique qui serait utilisée globalement.
// store/common.js
const state = (
erreurs : []
) ;
const actions = (
erreur : (
root : true,
handler(( commit ), error) (
commit("ERROR", erreur) ;
)
)
),
const mutations = (
ERROR (état, erreur) (
/* de cette façon, nous aurons l'erreur la plus récente en haut de la liste */
state.errors = [error, ...state.errors] ;
))
) ;
export const common (
namespaced : true,
état,
mutations
)
Nous pouvons maintenant adapter le utilisateur (ainsi que d'autres modules) :
essayer (
// une action
)catch (error) (
commit("common/ERROR", error, ( root : true )) ;
)
ou de manière plus élégante, en utilisant notre action globale :
try (
// une action
) catch (error) (
dispatch("error", erreur) ;
)
Cette syntaxe de s'engager
et envoi
Les appels semblent évidents, mais vous pouvez en savoir plus sur ces astuces ici.
Lorsque toutes les erreurs sont réunies en un seul endroit, vous pouvez facilement les charger dans votre Tableau de bord
de la composante :
calculé : mapState((
erreurs : 'common/errors'
)),
watch : (
/* ceci sera invoqué après chaque mutation "common/ERROR", où nous n'ajoutons que les nouvelles erreurs au magasin, une par une */
errors() (
this.showErrorMessage(this.errors[0]) ;
)
)
L'exemple précédent avec le commun La gestion des erreurs par module est déjà une solution efficace, mais vous pouvez aller encore plus loin.
Comme vous pouvez le voir, nous observons les changements sur le site de la commun/erreurs
dans le magasin. Dans des cas comme celui-ci, lorsque vous avez besoin de déterminer une action sur une mutation particulière, vous pouvez utiliser Vuex plugins ou même des composants d'ordre supérieur (HOC).
Je parlerai des plugins et des HOC dans le prochain article. En attendant, je vous remercie d'avoir lu cet article et j'espère que vous avez apprécié les exemples que nous avons préparés.
Restez à l'écoute et continuez à coder !
En savoir plus :
– Comment améliorer les applications Vue.js ? Quelques conseils pratiques
– GraphQL : leçons apprises en production
– Shopify, Spree ou Solidus ? Découvrez pourquoi Ruby on Rails peut vous aider à développer votre e-commerce.