dimanche 24 novembre 2024

[VueJS] [Composition API] transmettre et recevoir des données aux composants enfants (enfant <--> parent)

 Avec la Composition API de Vue.js, la gestion des props, des événements et des données suit un modèle différent, plus structuré et modulaire, qui permet de mieux organiser le code dans les composants. Voici les principaux changements pour la gestion des props et des événements avec la Composition API.




1. Gestion des props avec la Composition API

Avec Options API :

Dans l’Options API, les props sont définies dans l'objet props, et on y accède directement via this :

export default { props: { enPromotion: { type: Boolean, required: true } }, template: `<div v-show="enPromotion">🏷️ Produit en promotion !</div>` };

Avec Composition API :

Les props sont passées en tant qu’argument à la fonction setup(), où elles deviennent des objets réactifs (props).

Code équivalent :

<script setup> defineProps({ enPromotion: { type: Boolean, required: true } }); </script> <template> <div v-show="enPromotion">🏷️ Produit en promotion !</div> </template>

2. Transmission de données via props (parent → enfant)

Le fonctionnement est similaire entre Options API et Composition API. Cependant, avec la Composition API :

  • Définir les props est plus explicite grâce à defineProps.
  • Le code devient plus lisible et modulaire, car tout est géré dans setup ou via <script setup>.

Exemple complet (Parent → Enfant) :

Composant parent :

<template> <product-component :enPromotion="true" /> </template>

Composant enfant :

<script setup> defineProps({ enPromotion: Boolean }); </script> <template> <div v-show="enPromotion">🏷️ Produit en promotion !</div> </template>

3. Gestion des événements avec la Composition API

Avec Options API :

Dans l’Options API, on émet un événement avec this.$emit, et le parent écoute cet événement dans le template :

methods: { notifyParent() { this.$emit('add-to-cart', this.productId); } }

Avec Composition API :

Les événements sont émis avec la fonction emit, passée en tant qu'argument dans setup.

Code équivalent :

<script setup> import { defineEmits } from 'vue'; const emit = defineEmits(['add-to-cart']); function notifyParent(productId) { emit('add-to-cart', productId); } </script> <template> <button @click="notifyParent(123)">Ajouter au panier</button> </template>

4. Transmission des données avec des événements (enfant → parent)

Avec la Composition API, l'émission d'un événement reste similaire, mais le système est plus clair grâce à defineEmits. On peut également documenter explicitement les événements émis par le composant.

Exemple complet (Enfant → Parent) :

Composant enfant :

<script setup> defineEmits(['add-to-cart']); function ajouterProduit(productId) { emit('add-to-cart', productId); } </script> <template> <button @click="ajouterProduit(123)">Ajouter au panier</button> </template>

Composant parent :

<template> <product-component @add-to-cart="mettreDansPanier" /> </template> <script setup> function mettreDansPanier(productId) { console.log('Produit ajouté au panier :', productId); } </script>

5. Avantages de la Composition API

  • Meilleure organisation du code : Toutes les fonctionnalités liées à une fonctionnalité (props, événements, données) sont regroupées dans setup, ce qui simplifie les composants complexes.

  • Réutilisabilité accrue : Le code peut facilement être déplacé dans des composables (fonctions réutilisables), ce qui améliore la modularité.

  • Clarté explicite : Les fonctions comme defineProps et defineEmits documentent directement le contrat entre un composant et ses parents/enfants.


En résumé :

Avec la Composition API :

  • Les props sont définies avec defineProps et utilisées directement dans le template sans avoir besoin de this.
  • Les événements sont gérés avec defineEmits, ce qui rend leur usage plus explicite et documenté.
  • Le code est plus structuré et réutilisable, particulièrement utile pour les projets complexes. https://fr.vuejs.org/api/sfc-script-setup#defineprops-defineemits 

[VueJs] Transmettre des données aux composants enfants avec les props

Comment un composant parent peut transmettre des données à un composant enfant grâce aux props, en utilisant une propriété indiquant si un produit est en promotion.






1. Problème initial :

  • L'application est composée de deux composants principaux :
    • Composant Parent : Gère l'ensemble de la page et contient des données globales comme celles liées au panier.
    • Composant Enfant : Affiche les détails du produit, comme sa description ou des badges spécifiques.
  • Le composant enfant ne peut pas accéder directement aux données du parent.

2. Solution : Utiliser des props :

  • Les props permettent au composant parent de transmettre des données spécifiques à son enfant.

3. Étapes pour utiliser les props :

a) Déclarer une donnée dans le parent :

  • Dans le composant parent, on crée une donnée enPromotionProduct qui indique si le produit est en promotion.
data() { return { enPromotionProduct: true // Par défaut, le produit est en promotion }; }

b) Passer cette donnée au composant enfant :

  • Dans le template du parent, on transmet la donnée via un attribut personnalisé :
  • <product-component :enPromotion="enPromotionProduct"></product-component>

c) Déclarer et utiliser la prop dans l'enfant :

  1. Déclarer la prop dans le composant enfant pour qu'il puisse recevoir et utiliser cette donnée :
    props: { enPromotion: { type: Boolean, // La prop doit être de type booléen required: true // Cette prop est obligatoire } }
  2. Utiliser la prop dans le template du composant enfant. Par exemple, afficher un badge "Promotion" si la prop est vraie :
    <div v-show="enPromotion" class="promotion-badge"> 🏷️ Produit en promotion ! </div>

4. Résultat final :

  • Lorsque la donnée enPromotionProduct dans le parent est true, un badge "🏷️ Produit en promotion !" s'affiche dans le composant enfant.
  • Si cette donnée est modifiée dans le parent (par exemple, false), le composant enfant met automatiquement à jour son rendu, et le badge disparaît.

Points importants :

  1. Unidirectionnalité : Les props permettent un flux de données clair du parent → enfant.
  2. Validation des props : On peut préciser le type, rendre la prop obligatoire, ou même définir des valeurs par défaut.
  3. Dynamisme : Toute modification de la donnée dans le parent se répercute automatiquement sur l’enfant.

Avantages de l'exemple enPromotion :

Cet exemple montre clairement comment un composant parent peut contrôler le rendu du composant enfant de manière conditionnelle. Cela illustre aussi un cas d'usage réaliste pour des sites e-commerce, où des informations comme l'état de promotion d'un produit sont essentielles.

[VueJs] Émettre des événements depuis un composant enfant

 Comment émettre des événements personnalisés depuis un composant enfant pour communiquer avec un composant parent.



Voici les étapes clés :

  1. Problème initial :

    • L'application est structurée en deux composants :
      • Parent : Contient la page globale et le panier.
      • Enfant : Contient la description du produit.
    • En déplaçant le bouton "Ajouter" dans le composant enfant, le panier ne fonctionne plus, car il dépend d'une action dans le parent.
  2. Émission d’un événement :

    • Dans le composant enfant :
      • On utilise this.$emit('nom-de-l-evenement') pour informer le parent qu’une action s’est produite.
      • Exemple : Lorsqu'un utilisateur clique sur "Ajouter", l'événement personnalisé add-product est émis.
  3. Écoute par le parent :

    • Dans le composant parent :
      • On ajoute un écouteur d’événement avec @add-product="methodeParent".
      • Cette méthode implémente la logique, comme mettre à jour le panier.
  4. Transmission de données :

    • L'événement peut transporter des données via un second argument
    • Exemple :
      • this.$emit('add-product', price) dans l'enfant.
    • Dans le parent, la méthode liée peut récupérer ces données via $event.
      Exemple : addCard(price) { this.totalPrice += price; }
  5. Résultat final :

    • En cliquant sur "Ajouter", le composant enfant émet un événement avec le prix du produit.
    • Le parent écoute cet événement, récupère les données et met à jour le panier (quantité et total des prix).

Points importants :

  • Événements personnalisés sont une solution efficace pour la communication enfant → parent.
  • Transport de données : Les événements peuvent inclure des arguments pour transmettre des informations au parent.
  • Flexibilité : Ce mécanisme permet de maintenir une architecture de composants propre et modulaire.