→ Vue.js pour les débutants Leçon 1: Instance de Vue
→ Vue.js pour les débutants, Leçon 2: Liaison d'attributs
→ Vue.js pour les débutants, Leçon 3: Rendu conditionnel
→ Vue.js pour les débutants, Leçon 4: Listes de rendu
→ Vue .js pour les débutants leçon 5: traitement des événements
→ Vue.js pour débutants leçon 6: lier les classes et les styles
→ Vue.js pour débutants leçon 7: propriétés calculées
→ Vue.js pour débutants leçon 8: composants
→ Vue. js pour les débutants leçon 9: événements personnalisés
Le but de la leçon
Nous voulons que le composant
product
puisse dire à l'entité parente, l'instance racine de Vue, qu'un événement s'est produit. Dans ce cas, il product
doit envoyer, avec la notification de l'occurrence de l'événement, certaines données.
Code initial
L'exemple de fichier de
index.html
projet contient désormais le code suivant:
<div id="app">
<product :premium="premium"></product>
</div>
Voici le contenu du fichier
main.js
:
Vue.component('product', {
props: {
premium: {
type: Boolean,
required: true
}
},
template: `
<div class="product">
<div class="product-image">
<img :src="image" />
</div>
<div class="product-info">
<h1>{{ title }}</h1>
<p v-if="inStock">In stock</p>
<p v-else>Out of Stock</p>
<p>Shipping: {{ shipping }}</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div
class="color-box"
v-for="(variant, index) in variants"
:key="variant.variantId"
:style="{ backgroundColor: variant.variantColor }"
@mouseover="updateProduct(index)"
></div>
<button
v-on:click="addToCart"
:disabled="!inStock"
:class="{ disabledButton: !inStock }"
>
Add to cart
</button>
<div class="cart">
<p>Cart({{ cart }})</p>
</div>
</div>
</div>
`,
data() {
return {
product: 'Socks',
brand: 'Vue Mastery',
selectedVariant: 0,
details: ['80% cotton', '20% polyester', 'Gender-neutral'],
variants: [
{
variantId: 2234,
variantColor: 'green',
variantImage: './assets/vmSocks-green.jpg',
variantQuantity: 10
},
{
variantId: 2235,
variantColor: 'blue',
variantImage: './assets/vmSocks-blue.jpg',
variantQuantity: 0
}
],
cart: 0,
}
},
methods: {
addToCart() {
this.cart += 1;
},
updateProduct(index) {
this.selectedVariant = index;
console.log(index);
}
},
computed: {
title() {
return this.brand + ' ' + this.product;
},
image() {
return this.variants[this.selectedVariant].variantImage;
},
inStock() {
return this.variants[this.selectedVariant].variantQuantity;
},
shipping() {
if (this.premium) {
return "Free";
} else {
return 2.99
}
}
}
})
var app = new Vue({
el: '#app',
data: {
premium: true
}
})
Tâche
Maintenant qu'il
product
est présenté comme un composant autonome, cela product
n'a aucun sens que le code lié au panier y soit . Si chaque produit a son propre panier dont nous devons surveiller l'état, notre application deviendra un gros désordre. Au lieu de cela, nous aimerions que le panier existe à l'instance racine de Vue. Nous avons également besoin du composant pour product
informer l'instance racine de Vue sur l'ajout d'articles au panier, c'est-à-dire sur les clics sur le bouton Add to cart
.
Décision
Déplaçons les données liées au panier vers l'instance racine de Vue:
var app = new Vue({
el: '#app',
data: {
premium: true,
cart: 0
}
})
Ensuite, déplaçons le modèle de panier vers
index.html
, en apportant son code à ce formulaire:
<div id="app">
<div class="cart">
<p>Cart({{ cart }})</p>
</div>
<product :premium="premium"></product>
</div>
Maintenant, si vous ouvrez la page de l'application dans un navigateur et cliquez sur le bouton
Add to cart
, rien ne se passe comme prévu.
Cliquer sur le bouton Ajouter au panier n'aboutit encore à rien
. Que se passe-t-il lorsque vous cliquez sur ce bouton? Nous avons besoin qu'en cliquant dessus, l'instance racine de Vue reçoive une notification qui appellerait une méthode qui met à jour le panier, c'est-à-dire met à jour la valeur stockée dans
cart
.
Pour y parvenir, réécrivons d'abord le code de la méthode du
addToCart
composantproduct
.
Maintenant, cela ressemble à ceci:
addToCart() {
this.cart += 1;
},
Amenons-le sous cette forme:
addToCart() {
this.$emit('add-to-cart');
},
Qu'est-ce que tout cela signifie?
Voilà donc ce que c'est. Lorsque la méthode est appelée
addToCart
, un événement nommé personnalisé est généré add-to-cart
. En d'autres termes, lorsque le bouton Add to cart
est cliqué, une méthode est appelée qui génère un événement indiquant que le bouton vient d'être pressé (c'est-à-dire que l'événement déclenché par le clic du bouton vient de se produire).
Mais pour le moment, rien dans l'application n'attend que cet événement se produise ou ne l'écoute. Ajoutons un écouteur d'événement à
index.html
:
<product :premium="premium" @add-to-cart="updateCart"></product>
Ici, nous utilisons la construction de vue de la
@add-to-card
même manière que nous utilisons la construction :premium
. Mais s'il :premium
s'agit d'un "pipeline" à travers lequel des données peuvent être transmises au composant enfant depuis le parent, alors @add-to-cart
il peut être comparé au "récepteur radio" du composant parent, qui reçoit des informations du composant enfant selon lesquelles un bouton a été enfoncé Add to cart
. Puisque la "radio" est dans une balise <product>
imbriquée <div id="app">
, cela signifie que lorsque des informations sur un clic arrivent , la Add to cart
méthode updateCart
située dans l'instance racine de Vue sera appelée . Traduit en langage ordinaire, le
code
@add-to-cart=«updateCart»
ressemble à ceci: "Lorsque vous entendez qu'un événement s'est produit add-to-cart
, appelez la méthode updateCart
."
Cette méthode, qui sera maintenant déclarée dans l'objet options utilisé lors de l'instanciation de Vue, vous l'avez probablement vue quelque part:
methods: {
updateCart() {
this.cart += 1;
}
}
En fait, c'est exactement la même méthode qui a été utilisée plus tôt dans
product
. Mais maintenant, il se trouve dans l'instance racine de Vue et est appelé en cliquant sur un bouton Add to cart
.
Le bouton fonctionne à nouveau
Lorsque vous cliquez sur un bouton qui se trouve dans un composant
product
, une méthode est appeléeaddToCart
qui génère un événement. L'instance racine de Vue, écoutant la radio, apprend que l'événement s'est produit et appelle une méthodeupdateCart
qui incrémente le nombre stocké danscart
.
Nous avons atteint notre objectif, mais dans une application réelle, savoir qu'un événement s'est produit, qu'un certain produit a été ajouté au panier, n'apportera pas beaucoup d'avantages. En réalité, vous devez au moins savoir quel produit a été ajouté au panier. Cela signifie que dans l'événement généré en réponse à une pression sur le bouton, vous devez également transférer certaines données.
Les données passées dans l'événement peuvent être décrites comme le deuxième argument passé
$emit
dans le code de la méthode duaddToCart
composantproduct
:
this.$emit('add-to-cart', this.variants[this.selectedVariant].variantId);
Maintenant, l'événement transmet l'identifiant (
variantId
) du produit que l'utilisateur souhaite ajouter au panier. Cela signifie qu'au lieu de simplement augmenter le nombre d'articles dans le panier, nous pouvons aller plus loin et stocker des informations plus détaillées sur les articles qui y sont ajoutés dans le panier. Pour ce faire, nous convertissons d'abord le panier en tableau en écrivant un tableau vide dans cart
:
cart: []
Ensuite, réécrivons la méthode
updateCart
. Premièrement - il acceptera maintenant id
- le même identifiant de produit qui est maintenant passé dans l'événement, et deuxièmement - il mettra maintenant ce qu'il a reçu dans un tableau:
methods: {
updateCart(id) {
this.cart.push(id);
}
}
Après un simple clic sur le bouton, l'identifiant du produit est ajouté au tableau. Le tableau est affiché sur la page.
La baie avec l'ID de produit est affichée sur la page.
Nous n'avons pas besoin d'afficher la baie entière sur la page. Nous serons satisfaits de la sortie du nombre de produits ajoutés au panier, c'est-à-dire au tableau
cart
. Par conséquent, nous pouvons réécrire le code de l'étiquette<p>
, qui affiche des informations sur le nombre de produits ajoutés au panier, comme ceci:
<p>Cart({{ cart.length }})</p>
La page affiche des informations sur le nombre d'articles ajoutés au panier.
Maintenant, nous affichons simplement la longueur du tableau sur la page, ou, en d'autres termes, le nombre d'articles dans le panier. Extérieurement, le panier a le même aspect qu'avant, mais maintenant, au lieu d'augmenter simplement la valeur d'une propriété numérique
cart
, nous stockons dans un tableau descart
informations sur l'article qui a été ajouté au panier.
Atelier
Ajoutez un bouton au projet qui supprime le
cart
produit ajouté précédemment du tableau . En cliquant sur ce bouton, un événement doit être généré contenant des informations sur l'identifiant de l'article à retirer du panier.
Résultat
Voici ce que vous avez appris aujourd'hui:
- Un composant peut informer l'entité parente que quelque chose s'est passé en lui en utilisant la construction
$emit
. - Un composant parent peut utiliser un gestionnaire d'événements défini à l'aide de la directive
v-on
(ou de sa version abrégée@
) pour organiser une réponse aux événements générés par les composants enfants. Si un événement se produit, un gestionnaire d'événements peut être appelé dans le composant parent. - , , .
Si vous étudiez le cours et que vous avez atteint cette leçon, veuillez nous indiquer le but pour lequel vous faites, ce que vous voulez réaliser en maîtrisant Vue.
→ Vue.js débutants leçon 1: instance Vue
→ Vue.js pour les débutants, leçon 2: attributs de liaison
→ Vue.js débutants leçon 3: rendu conditionnel
→ Vue.js débutants leçon 4: rendu des listes
→ Vue .js pour les débutants leçon 5: traitement des événements
→ Vue.js débutants leçon 6: classes et styles de liaison
→ Vue.js débutants leçon 7: propriétés calculées
→ Vue.js débutants leçon 8: composants
→ Vue. js pour les débutants leçon 9: événements personnalisés