Le basculement entre les pages Vue Router provoque le déclenchement de plusieurs événements sur VueJS monté ()

Aug 16 2020

Je travaille sur un projet Electron où j'utilise le projet Vue CLI et le plugin Vue CLI Electron Builder . Tout fonctionne très bien sauf un bug étrange que j'ai trouvé récemment.

Chaque fois que je navigue entre les pages (Vue Router), l'événement que j'écoute depuis la mounted()propriété du composant devient double. C'est en fait le N+1problème.

pour décrire le problème plus clairement, j'ai deux éléments Home.vueet HelloWorld.vue. À partir du Home.vuecomposant, j'envoie un événement au mainprocessus chaque fois que je clique sur un bouton et écoute le event.reply()depuis la même mounted()propriété de composant . C'est tout à fait comme prévu à ce stade.

Cependant, chaque fois que je vais sur la HelloWorldpage et que je reviens à la Homepage et que je clique sur le bouton pour envoyer et recevoir le eventdu mainprocessus, je ne vois pas seulement un seul eventmême si je clique une seule fois mais je vois deux eventréponses . Si je change de page à nouveau, je vois trois eventréponses et ainsi de suite N+1.

Pour votre commodité, j'ai créé un GIF rapide qui montrera clairement le problème.

Home.vue

<template>
  <div class="home">
    <button @click="send()">Home</button>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      cause: null
    }
  },
  mounted() {
    window.ipcRenderer.on("home:reply", event => console.log(event));
  },
  methods: {
    send() {
      window.ipcRenderer.send("home");
    }
  },
};
</script>

main.js

ipcMain.on("home", event => {
  return event.reply("home:reply");
});

Je n'ai rien de spécial sur le routeur Vue et c'est juste l'échafaudage par défaut fourni avec la CLI Vue. Comme vous pouvez le voir dans l'extrait de code ci-dessus, tout ce que je fais, c'est simplement envoyer un événement en cliquant sur un bouton et en écoutant la même réponse d'événement à partir de la même mounted()propriété de composant .

J'ai également trouvé un sujet similaire sur Stack Overflow mais je n'ai pas pu le comprendre moi-même. Je n'ai aucune idée de ce qui ne va pas sur mon code 🥱

Réponses

2 DecadeMoon Aug 16 2020 at 19:56

Vous devez désinscrire le gestionnaire d'événements lorsque le composant est détruit, sinon vous continuerez à enregistrer le même gestionnaire d'événements encore et encore chaque fois que le composant est monté.

mounted() {
  window.ipcRenderer.on('home:reply', this.handleHomeReply)
},

destroyed() {
  window.ipcRenderer.off('home:reply', this.handleHomeReply)
},

methods: {
  handleHomeReply(event) {
    console.log(event)
  }
}