Vueルーターページを切り替えると、VueJSmounted()で複数のイベントが発生します

Aug 16 2020

私はVueCLIプロジェクトとVueCLIプラグインElectronBuilderを使用するElectronプロジェクトに取り組んでいます。私が最近見つけた奇妙なバグを除いて、すべてがうまく機能します。

ページ間(Vue Router)を移動するたびに、コンポーネントmounted()プロパティからリッスンするイベントが2倍になります。それは実際にN+1問題です。

問題をより明確に説明するために、2つのコンポーネントがHome.vueありHelloWorld.vueます。Home.vueコンポーネントからmain、ボタンをクリックevent.reply()して同じコンポーネントmounted()プロパティからをリッスンするたびに、プロセスにイベントを送信しています。この段階では完全に予想通りです。

ただし、HelloWorldページに移動してHomeもう一度ページに戻り、ボタンをクリックeventしてmainプロセスからの送受信を行うと、event1回だけクリックしても、1つだけでなく、2つのevent返信が表示されます。。もう一度ページを切り替えるeventと、3つの返信などが表示されN+1ます。

便宜上、問題を明確に示す簡単なGIFを作成しました。

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

Vueルーターには特別なことは何もありません。VueCLIに付属しているのはデフォルトのスキャフォールドです。上記のコードスニペットでわかるように、私が行っているのは、ボタンをクリックしたときにイベントを送信し、同じコンポーネントmounted()プロパティから同じイベント応答をリッスンすることだけです。

Stack Overflowでも同様のトピックを見つけましたが、自分で理解できませんでした。コードのどこが悪いのかわかりません🥱

回答

2 DecadeMoon Aug 16 2020 at 19:56

コンポーネントが破棄されたときにイベントハンドラーの登録を解除する必要があります。そうしないと、コンポーネントがマウントされるたびに同じイベントハンドラーを何度も登録し続けることになります。

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

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

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