การสลับระหว่างหน้า Vue Router ทำให้เกิดเหตุการณ์ไฟไหม้หลายครั้งบน VueJS ที่ติดตั้ง ()

Aug 16 2020

ฉันกำลังทำงานอยู่บนElectronโครงการที่ผมใช้โครงการ Vue CLI และVue CLI ปลั๊กอิน Electron Builder ทุกอย่างใช้งานได้ดียกเว้นข้อบกพร่องแปลก ๆ ที่ฉันพบเมื่อเร็ว ๆ นี้

เมื่อใดก็ตามที่ฉันเลื่อนไปมาระหว่างเพจ (Vue Router) เหตุการณ์ที่ฉันฟังจากmounted()คุณสมบัติคอมโพเนนต์จะกลายเป็นสองเท่า มันเป็นN+1ปัญหาจริง

เพื่ออธิบายปัญหาให้ชัดเจนยิ่งขึ้นฉันมีสององค์ประกอบHome.vueและ HelloWorld.vueจากHome.vueองค์ประกอบฉันกำลังส่งเหตุการณ์ไปยังmainกระบวนการเมื่อใดก็ตามที่คลิกปุ่มและฟังevent.reply()จากmounted()คุณสมบัติของส่วนประกอบเดียวกัน เป็นไปตามที่คาดไว้ในขั้นตอนนี้

อย่างไรก็ตามเมื่อใดก็ตามที่ฉันไปที่HelloWorldหน้าและเปลี่ยนกลับไปที่Homeหน้านั้นอีกครั้งและเมื่อฉันคลิกปุ่มเพื่อส่งและรับeventจากmainกระบวนการฉันไม่เห็นเพียงข้อความเดียวeventแม้ว่าฉันจะคลิกเพียงครั้งเดียวเท่านั้น แต่ฉันเห็นสองeventคำตอบ . ถ้าฉันสลับไปมาระหว่างหน้าอีกครั้งฉันจะเห็นการeventตอบกลับสามครั้งและ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 Router และเป็นเพียงโครงนั่งร้านเริ่มต้นที่มาพร้อมกับ Vue CLI ดังที่คุณเห็นในข้อมูลโค้ดด้านบนสิ่งที่ฉันทำมีเพียงแค่ส่งเหตุการณ์เมื่อคลิกปุ่มและรับฟังการตอบกลับเหตุการณ์เดียวกันจาก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)
  }
}