Alternar entre as páginas do Vue Router causa o disparo de vários eventos no VueJS montado ()

Aug 16 2020

Estou trabalhando em um projeto Electron onde uso o projeto Vue CLI e o Vue CLI Plugin Electron Builder . Tudo funciona bem, exceto um bug estranho que descobri recentemente.

Sempre que navego entre as páginas (Vue Router), o evento que escuto na mounted()propriedade do componente torna-se duplo. É realmente o N+1problema.

para descrever o problema com mais clareza, tenho dois componentes Home.vuee HelloWorld.vue. Do Home.vuecomponente, estou enviando um evento ao mainprocesso sempre que clico em um botão e ouço a event.reply()partir da mesma mounted()propriedade do componente . Está completamente conforme o esperado neste estágio.

No entanto, sempre que vou para a HelloWorldpágina e volto para a Homepágina novamente e quando clico no botão para enviar e receber o eventdo mainprocesso, não vejo apenas um event, embora clique apenas uma vez, mas vejo duas eventrespostas . Se eu alternar entre as páginas novamente, verei três eventrespostas e assim por diante N+1.

Para sua conveniência, criei um GIF rápido que mostrará o problema claramente.

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");
});

Não tenho nada de especial no Vue Router e é apenas um andaime padrão que vem com o Vue CLI. Como você pode ver no trecho de código acima, tudo o que estou fazendo é apenas enviar um evento ao clicar em um botão e ouvir a mesma resposta de evento da mesma mounted()propriedade do componente .

Eu também encontrei um tópico semelhante no Stack Overflow, mas não consegui descobrir sozinho. Não tenho ideia do que há de errado no meu código 🥱

Respostas

2 DecadeMoon Aug 16 2020 at 19:56

Você precisa cancelar o registro do manipulador de eventos quando o componente for destruído, caso contrário, você apenas continuará registrando o mesmo manipulador de eventos sempre que o componente for montado.

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

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

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