web-dev-qa-db-fra.com

VueJS - déclenche la fonction enfant

Je suis nouveau à l'aide de vuejs (2.0). J'essaie d'obtenir cette fonctionnalité:

  • Cliquez sur un bouton 
  • Fonction de déclenchement dans le composant enfant
  • Incrément numéro dans les données de l'enfant

C'est ce que j'ai actuellement

HTML: 

<div id="root">
    <cart @addtocart="add()"></cart>
    <button @click="$emit('addtocart')">Add to Cart</button>
</div>

JS:

Vue.component('cart', {
  template: `<span>{{ items }}</span>`,
  data() {
    return {
      items: 0
    }
  },
  methods: {
    add() {
      alert('add');
    }
  }
});


new Vue({
  el: '#root',
  components: ['cart'],
});

Toute aide serait grandement appréciée. Merci tout le monde!

7
Grant Vinson

Vous pouvez utiliser un concentrateur centralisé pour émettre des événements (comme indiqué dans la documentation https://vuejs.org/v2/guide/migration.html#dispatch-and-broadcast-replaced ), puis écouter et réagir à ces événements à l'intérieur de vos composants enfants. Voici une mise à jour rapide de votre code qui fait cela:

var eventHub = new Vue();

Vue.component('cart', {
  template: `<span>{{ items }}</span>`,
  data() {
    return {
      items: 0
    }
  },
  created() {
    eventHub.$on('add-item', this.add)
  },
  methods: {
    add() {
      alert('add');
      this.items++;
    }
  }
});


new Vue({
  el: '#root',
  components: ['cart'],
  methods: {
    addToCart() {
        eventHub.$emit('add-item')
    }
  }
});

Je viens juste de commencer à utiliser moi-même la vue et je me trompe peut-être, mais autant que je sache, le fait d'avoir un composant enfant dépendant d'un parent spécifique est une mauvaise idée, car il oblige le composant enfant à être "couplé" à ce parent pour fonctionner et le rend pas portable. Il est correct d’émettre des événements à partir d’un composant enfant, car c’est le composant qui permet à toute personne qui écoute de savoir que quelque chose s’est passé. Je suppose que vous pouvez accéder au parent et aux événements qu'il a émis directement en utilisant this.$parent.$on('add-item', this.method), mais cela me semble ridicule. Peut-être que si vos composants racine et enfant seront toujours étroitement couplés de cette façon, this.$parent conviendra. L'exemple ci-dessus "instancier une nouvelle instance de vue" est probablement juste un autre moyen de le faire sans lier votre composant enfant à un composant parent puisque les instances Vue implémentent le système d'événements (exposant ainsi les méthodes $ emit, $ on)

10
georaldc

Cela fonctionne très bien avec l'accès à la method avec $children sur le Parent Vue Component et cela simplifie les choses:

<div id="main-component">

   <!-- BUTTON on Main Component that will trigger the method in Child Component -->
   <button @click="$children[0].coolMethod();">I will trigger the a method on Child Component</button>

   <!-- CHILD Component -->
   <some-component-that-has-cool-method></some-component-that-has-cool-method>
</div>

Remarque: $children[0] car nous nous référons à la method qui est à index 0.

Il y a d'autres moyens d'y parvenir et ils sont décrits ici .

Voici un extrait de cette discussion:

Tout comme il existe un parent $ pour un composant qui est un enfant de Un autre, il existe un enfant ($ enfants? Je ne me souviens plus très bien) de Composants enfant, mais vous pouvez simplement ajouter une référence à votre composant pour rendre un peu plus clair peut-être.

Bonne chance....

0
Akash