Przełączanie między stronami Vue Router powoduje uruchamianie wielu zdarzeń na zamontowanym VueJS ()

Aug 16 2020

Pracuję nad projektem Electron , w którym używam projektu Vue CLI i Vue CLI Plugin Electron Builder . Wszystko działa świetnie, z wyjątkiem dziwnego błędu, który niedawno znalazłem.

Ilekroć nawiguję między stronami (Vue Router), zdarzenie, którego nasłuchuję z mounted()właściwości komponentu, staje się podwójne. Właściwie to jest N+1problem.

żeby dokładniej opisać problem mam dwa Home.vuei HelloWorld.vuepodzespoły. Z Home.vuekomponentu wysyłam zdarzenie do mainprocesu za każdym razem, gdy klikam przycisk i nasłuchuję event.reply()z tej samej mounted()właściwości komponentu . Na tym etapie wszystko jest zgodne z oczekiwaniami.

Jednak za każdym razem, gdy przechodzę do HelloWorldstrony i przełączam się z powrotem na Homestronę, a kiedy klikam przycisk, aby wysłać i odebrać eventz mainprocesu, nie widzę tylko jednego, eventmimo że klikam tylko raz, ale widzę dwie eventodpowiedzi . Jeśli ponownie przełączę się między stronami, zobaczę trzy eventodpowiedzi i tak dalej, jak N+1problem.

Dla Twojej wygody zrobiłem szybki GIF, który jasno pokaże problem.

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

Nie mam nic specjalnego na routerze Vue, a to tylko domyślne rusztowanie, które jest dostarczane z Vue CLI. Jak widać na powyższym fragmencie kodu, wszystko, co robię, to po prostu wysyłanie zdarzenia po kliknięciu przycisku i nasłuchiwanie tej samej odpowiedzi na zdarzenie z tej samej mounted()właściwości komponentu .

Znalazłem również podobny temat na Stack Overflow, ale sam nie mogłem tego rozgryźć. Nie mam pojęcia, co jest nie tak w moim kodzie 🥱

Odpowiedzi

2 DecadeMoon Aug 16 2020 at 19:56

Musisz wyrejestrować procedurę obsługi zdarzeń, gdy składnik zostanie zniszczony, w przeciwnym razie będziesz po prostu rejestrować tę samą procedurę obsługi zdarzeń za każdym razem, gdy komponent zostanie zamontowany.

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

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

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