web-dev-qa-db-fra.com

Méthode Vue.js appelée plusieurs fois en utilisant $ emit et $ on alors qu'elle ne doit être appelée qu'une seule fois

J'utilise un bus pour permettre aux composants d'interagir avec d'autres composants via la méthode décrite dans ce lien: https://forum.vuejs.org/t/create-event-bus-in-webpack-template/ 4546/2 .

J'ai une méthode qui est appelée dans le crochet créé qui utilise le bus pour émettre un événement.

created () {
  this.getReviewDeck()
},
myMethod () {
    bus.$emit('increment')
}

Dans un autre composant (qui est contenu dans le composant ci-dessus), j'attache l'écouteur d'événements dans le crochet créé comme ci-dessous:

created () {
  bus.$on('increment', this.incrementCount)
},
incrementCount () {
  console.log('count incremented')
}

Si je visite le composant la première fois, tout fonctionne correctement et la console enregistrera une fois le "nombre incrémenté". Cependant, si je quitte le composant et que j'y retourne la prochaine fois, 'count incremented' sera enregistré deux fois, et si je quitte et reviens, il sera maintenant enregistré trois fois, etc.

Je n'arrive pas à comprendre exactement ce qui se passe ou comment résoudre au mieux ce problème afin que chaque fois que j'accède au composant, le message ne soit enregistré qu'une seule fois au lieu de plusieurs fois.

12
dpst

J'ai dû supprimer le gestionnaire d'événements lors de la destruction.

 beforeDestroy () {
    EventBus.$off('increment', this.incrementCount)
 },
31
dpst

Vous pouvez utiliser $ .once

created () {
  bus.$once('increment', this.incrementCount)
},
7
Jdmiguel

Cela fonctionne dans le cas si vous souhaitez effectuer une action une seule fois après l'émission de l'événement. Et si vous voulez continuer à écouter un événement, par exemple: si vous survolez un point de données sur un graphique, vous voulez déclencher une action d'un autre composant. Dans ce cas, l'utilisation de $ once ne fonctionne pas. Je suis confronté au même problème lorsque j'émets un événement sur un survol et son abonnement en utilisant $ on, il ne devrait être appelé qu'une seule fois mais dans mon cas, il sera appelé plusieurs fois.

C'est ainsi que j'émets l'événement;

this.$eventBus.$emit("SHOW_HOVERLINE", d);

C'est ainsi que je souscris à l'événement;

this.$eventBus.$on("SHOW_HOVERLINE", this.someFunction);
1
Rushikesh Mhetre

On dirait que quelque chose a changé dans Vue code source, comme désactiver les écouteurs eventBus dans destroy ou beforeDestroy ou beforeRouteLeave ou tout autre hook fait ce qui suit - les anciens écouteurs sont supprimés avec les nouveaux écouteurs qui sont réenregistrés dans le crochet créé.

Pour les hooks détruits et beforeDroy, il est compréhensible car ils sont appelés après le hook créé. Ainsi created () ajoute des écouteurs, et destroy () les supprime tous, pas seulement ceux des précédents created (). Mais pour les hooks de route, je ne comprends pas le comportement, car ils sont appelés avant create () mais les mêmes écouteurs réenregistrés ne fonctionnent pas.

Ce que j'ai fait, c'est désactiver les écouteurs eventBus dans le hook créé avant de les réinscrire

created() {
  eventBus.$off("someListener");
  eventBus.$on("someListener", () => {
    // do smth
  })
}

Mais cela ne fonctionne que si le composant est recréé, s'il n'est créé qu'une seule fois pendant le cycle de vie de l'application, l'écouteur enregistré ne fonctionnera pas. Mais si le composant est créé une fois, nous n'avons pas besoin de ce réenregistrement.

0
Alonad

Pour supprimer tous les écouteurs:

his.$eventBus.$off()
0
omarjebari