Fermer

septembre 10, 2018

Comment émettre des données dans Vue: au-delà de la documentation de Vue.js


Dans ce blog, nous apprenons à émettre des événements à partir de composants enfants dans Vue, ainsi qu'à émettre à partir de composants enfants imbriqués. Nous faisons tout cela en évitant un anti-pattern commun que font souvent les nouveaux développeurs Vue.

La capacité d'encapsuler des données et une interface utilisateur dans des composants modulaires et réutilisables est un concept fondamental de nombreux frameworks et bibliothèques JavaScript modernes. C'est très utile pour aider un développeur à éviter de répéter des morceaux de code dans une application (ou même entre des applications). Cependant, alors que la capacité à contenir des fonctionnalités à l'intérieur d'un composant est grande, un composant aura souvent besoin de moyens pour communiquer avec le monde extérieur ou, plus spécifiquement, avec d'autres composants.

Nous pouvons envoyer des données vers le bas à partir d'un composant parent via des accessoires (abréviation de propriétés). C'est généralement un concept assez simple à saisir. Mais qu'en est-il de l'envoi de données d'un composant enfant à son parent?

Dans Vue, j'ai d'abord eu un peu de mal à le faire, principalement parce que je pense que la documentation de Vue ne couvre pas cela. aussi minutieux que possible (ce qui est dommage, car les documents de Vue excèdent souvent la plupart des autres domaines).

Après beaucoup de recherches sur Google (et d'essais et d'erreurs), j'ai fini par trouver un moyen d'envoyer des données de haut en bas. à un parent, mais après un certain temps, j'ai appris par un autre développeur que je l'avais fait complètement dans le mauvais sens – cela fonctionnait, mais je commettais un péché cardinal dans le monde des anti-modèles.

Avec tous Dans cet esprit, nous allons écrire un article qui, espérons-le, aidera les futurs développeurs de Vue à trouver une réponse claire à "comment émettre des données dans Vue", tout en construisant une petite application de panier d'achat intéressante. [19659007] Setup

Nous allons utiliser Vue CLI pour obtenir rapidement du code passe-partout, ainsi que toutes les Parmi les autres bonnes choses qu’elle apporte, comme le rechargement de modules à chaud, la compilation automatique, etc. Ne vous inquiétez pas si vous ne vous posez pas la question. 1965

Nous allons essayer de ne pas passer trop de temps à effectuer d’autres configurations, car l’objectif est de vous montrer comment émettre des données, plutôt que de vous montrer une configuration pas à pas de notre Application panier N'hésitez surtout pas à en créer un vous-même avec les exemples de code jalonnés dans l'article.

 Interface utilisateur Kendo Vue

Visitez cli.vuejs.org pour Plus d'informations sur l'installation et l'utilisation de Vue CLI.

L'application de panier d'achat terminée pour cet article est également disponible ici: github.com/sunil-sandhu/vue-cart-emit-example

Ce qu'est même une émission?

Une définition tirée de Cambridge Dictionary nous dit que la définition formelle de "émettre" est "d'envoyer un faisceau, du bruit, une odeur ou un gaz". Ne vous inquiétez pas, notre application n'émettra pas d'odeurs ni de gaz étranges! Dans notre cas, le but est "d'émettre" un signal – un signal provenant d'un composant enfant pour informer un composant parent qu'un événement a eu lieu (par exemple, un événement de clic). Généralement, le composant parent effectuera une sorte d'action, telle que l'exécution d'une fonction.

Comment émettre à partir d'un composant enfant

Jetons un coup d'œil à ce que nous voulons émettre. 19659003] À chaque fois qu'un utilisateur clique sur l'un des boutons Ajouter au panier nous voulons que l'élément en question soit ajouté à notre panier. Cela semble assez simple. Nous devons également nous rappeler que, avec une application basée sur des composants, chaque élément de la boutique est son propre composant (le nom du composant ici est Shop-Item ). Lorsque nous cliquons sur le bouton situé à l'intérieur de Shop-Item.vue les données doivent être renvoyées à leur parent pour que le panier soit mis à jour.

Voyons d'abord le code obtenu.



  


 

Décomposons cela et montrons simplement les parties surlignées et expliquons comment le clic d'un bouton déclenche une chaîne d'événements.

D'abord, nous avons un bouton dans Shop-Item.vue :

Chaque article de la boutique (Banane, Orange, Apple) possède l'un de ces boutons. Quand on clique dessus, notre écouteur d'événement @ click = "addToCart (item) est déclenché. Vous pouvez voir qu'il prend l'élément en paramètre (c'est l'objet objet entier passé dans [19659030] comme un prop.) Lorsque le bouton est cliqué, il déclenche la fonction addToCart :

 addToCart (item) {
  this. $ emit ('update-cart', item)
} 

Nous voyons que cette fonction déclenche ceci. $ Emit . Qu'est ce que ça veut dire? Eh bien, émettre envoie simplement un signal. Dans ce cas, le signal est "update cart", qui est envoyé sous la forme d'une chaîne. Donc, essentiellement, this. $ Emit prend comme premier paramètre une chaîne . Il peut également accepter un second paramètre, qui prendra généralement la forme d'une partie de données que nous souhaitons lui envoyer. Il pourrait s'agir d'une autre chaîne d'un entier d'une variable, d'un tableau ou, dans notre cas, d'un . ] Mais alors, comment envoyer cette chaîne de "update-cart" avertit notre composant parent que le panier doit être mis à jour? Eh bien, regardons le troisième morceau du puzzle.

Lorsque nous ajoutons notre balise dans App.vue nous ajoutons également un écouteur d'événement personnalisé qui écoute update-cart . En fait, il ressemble en fait à notre écouteur d'événement @click figurant sur les boutons « Ajouter au panier ».

  
 

Nous voyons ici que notre écouteur d'événement personnalisé attend que l'événement update-cart soit déclenché. Et comment sait-il que cela se produit? Lorsque la chaîne 'update-cart' est émise depuis l'intérieur de Shop-Item.vue !

Le dernier bit consiste maintenant à voir ce qui se passe quand cet événement @ update-cart l'écouteur déclenche la fonction updateCart :

 updateCart (e) {
  this.cart.push (e);
  this.total = this.shoppingCartTotal;
} 

Cela prend simplement un paramètre d'événement et l'insère dans le tableau this.cart . L'événement qu'il prend est simplement l'élément que nous avons initialement placé comme second paramètre lorsque nous avons appelé this. $ Emit . Vous pouvez également voir que this.total est également mis à jour pour renvoyer le résultat de la fonction this.shoppingCartTotal (consultez le dépôt Github pour plus d'informations sur la façon dont il le fait).

Et c'est ainsi que nous émettons d'un composant enfant vers le composant parent. Nous pouvons même voir cela se dérouler à l'intérieur de Outils de développement Vue (un élément essentiel du kit si vous utilisez Chrome et que vous travaillez avec des composants Vue). Lorsque le bouton "Ajouter au panier" est pressé pour la banane, toutes les informations de la capture d'écran ci-dessous sont affichées:

 Interface utilisateur Kendo Vue

le bouton "Ajouter au panier" de la banane.

Génial, nous savons maintenant comment émettre correctement à partir d'un composant enfant vers le parent! Que se passe-t-il si des composants enfants se trouvent à l'intérieur d'autres composants enfants? Comment émettons-nous un message jusqu'au parent (ou au grand-parent, si cela vous facilite la visualisation)?

Comment émettre à partir d'un composant enfant imbriqué (c.-à-d. Petit-enfant à grand-parent)

Bon, prenant le même exemple que lorsque nous émettons d'un enfant à l'autre, nous allons le prendre Un pas en avant. Dans notre code fini, nous avions en fait le bouton "Ajouter au panier" comme composant, qui se trouve à l'intérieur de Shop-Item.vue (avant que le bouton ne soit placé à l'intérieur du composant Shop-Item). comme un bouton normal, mais maintenant nous l'avons transformé en un composant réutilisable.

Pour vous donner un schéma brut de cette structure, voir ci-dessous:

App.vue < Shop-Item.vue < Shop-Button-Add.vue

Shop-Button-Add.vue est niché à l'intérieur de Shop-Item.vue qui est imbriqué à l'intérieur de App.vue .

Ce que nous devons faire ici, c'est trouver un moyen d'émettre un événement depuis Shop-Button-Add.vue jusqu'à Shop-Item.vue qui déclenche ensuite un événement d'émission de Shop-Item.vue à App.vue . Cela semble un peu compliqué, mais c'est en fait plus facile que vous ne le pensez.

Voici les blocs de code qui rendent cela possible.

Dans Shop-Button-Add.vue :

  

Qui déclenche cette méthode dans le même fichier:

 méthodes: {
  buttonClicked () {
    this. $ emit ('bouton-cliqué')
  }
} 

A l'intérieur de Shop-Item.vue, nous attachons un écouteur @ sur un bouton sur le tag :


  

Ajouter au panier

Nous voyons ici que nous transmettons également l'objet item en tant que paramètre (exactement comme dans l'exemple précédent). Cet écouteur d'événement @ sur lequel un clic sur le bouton déclenche la fonction suivante dans le même fichier:

 méthodes: {
  addToCart (item) {
    this. $ emit ('update-cart', item)
  }
} 

À l'intérieur de App.vue, nous attachons un écouteur @ update-cart au tag :

  
 

Enfin, cela déclenche la fonction updateCart qui se trouve dans App.vue en tant que telle:

 méthodes: {
  updateCart (e) {
    this.cart.push (e);
    this.total = this.shoppingCartTotal;
  }
} 

Qui pousse l'objet objet dans le panier. Et c'est comme ça que nous émettons des composants imbriqués!

Mais qu'en est-il des composants très profondément imbriqués (p. Ex., Grand-arrière-arrière-arrière-arrière-arrière-arrière-arrière-arrière-grand-père)?

Eh bien, nous avons trois options ici:

  1. Vous pourriez émettre votre événement en remontant la chaîne (bien que cela puisse commencer à être assez compliqué si vous devez émettre davantage). que petit-enfant à grand-parent).
  2. Vous pouvez utiliser un système de gestion d’état dédié tel que Vuex ce qui peut aider à simplifier le processus d’émission de composants profondément imbriqués. Je recommanderais certainement cet itinéraire et nous chercherons certainement à le couvrir dans un prochain article!
  3. Ou vous pourriez utiliser quelque chose appelé Global Event Bus . Vous pouvez penser à ceci comme implémentant votre propre version simplifiée d'un système de gestion d'état tel que Vuex. Cependant, il convient de noter que l'équipe principale de Vue déconseille généralement l'utilisation de Global Event Buses en faveur de quelque chose de plus robuste, tel que Vuex. Nous n'irons pas plus loin dans les raisons pour cela, mais cela vaut certainement la peine de chercher plus loin si c'est quelque chose que vous envisagez dans votre application.

Les coupables anti-pattern

La raison pour laquelle il est vraiment important d'avoir notre émettre des écouteurs d'événements correctement est parce que nous essayons en fin de compte d'encapsuler nos composants le mieux possible. Dans le cas d'un bouton, plus nous pouvons le rendre réutilisable, plus il devient transportable. Si notre bouton émet une simple chaîne avec un bouton, nous pouvons alors décider ce que nous voulons que cet événement émette se déclenche sur une base par application – nous pourrions même le déclencher de différentes manières à l'intérieur de la même application.

Comme mentionné au début de cet article, lorsque j'ai découvert comment émettre des événements pour la première fois, j'ai fini par utiliser les deux syntaxes suivantes: this. $ parent. $ emit et this. $ Root. $ Emit .

Bien qu'ils ressemblent à ceci. $ Emit ils sont différents dans le sens que this. $ Parent. $ emit émet l'événement à l'intérieur du composant parent, alors que this. $ root. $ emit émet l'événement à l'intérieur du composant racine (qui dans notre exemple aurait été App .vue )

Donc, si nous prenons notre composant Shop-Button-Add cela émet un signal vers le haut Shop -Item par l'utilisation de ce. $ Emit . Cependant, si nous avons choisi d'utiliser this. $ Parent. $ Emit, ceci indiquera en réalité à Shop-Item d'émettre un événement à la place. Effectivement, le Shop-Button-Add indique maintenant à son parent Shop-Item d'émettre un événement, plutôt que de suivre le modèle approprié d'émission d'événements.

Il est un peu déroutant de vous embrouiller quelquefois, et pour être honnête, dans notre exemple, il peut être utile de sauter une étape et de passer à this. $ parent. $ emit . Cependant, le problème est que notre Shop-Button-Add n'est plus vraiment encapsulé, car il repose désormais sur le fait qu'il soit toujours présent dans Shop-Item pour qu'il fonctionne. Encore une fois, cela peut sembler acceptable dans le cas de notre application de panier d'achat simple, mais si nous voulions généraliser notre bouton et en faire un Shop-Button utilisé dans notre application pour beaucoup de des choses différentes, telles que l'augmentation / la diminution des quantités, la vidange de notre chariot, etc. Ce serait très compliqué et très déroutant très vite!

Pour résumer rapidement ceci. $ parent et this. $ root:

  • this. $ emit distribue un événement à son composant parent
  • this. $ parent vous donne une référence au composant parent
  • this. $ root vous donne une référence au composant racine
  • ceci. $ Parent. $ Emit obligera le parent à envoyer l'événement à son parent
  • this. $ Root. $ Emit fera de la distribution racine l'événement lui-même

Conclusion

Et voilà! Nous savons maintenant comment émettre avec succès des événements et des données à partir de composants enfants, et même des composants enfants imbriqués, jusqu'au parent. Nous avons également appris l'existence de ce. $ Parent et de cette. $ Root, mais pourquoi ils devraient être évités et sont considérés comme provoquant un anti-pattern. Suite à cela, je vous recommande vivement d’écouter cet épisode de Full Stack Radio Chris Fritz membre de la Vue Core Team, parle davantage des anti-patterns communs qu’il a remarqués.

Si vous avez trouvé cela utile, assurez-vous de partager, et n'hésitez pas à me contacter sur Twitter pour en discuter davantage.

For More Vue

Want en savoir plus sur Vue? Découvrez la série de vidéos sur Premiers pas avec Kendo UI et Vue pour apprendre à créer une excellente interface utilisateur dans Vue ou consultez la bibliothèque de composants Kendo UI for Vue .


Les commentaires sont désactivés en mode aperçu.






Source link