admin管理员组

文章数量:1302319

I have a Vue2 ponent which contains an added eventListener i created on mounted. I was wondering how do i properly remove this listener when the ponent is destroyed?

<template>
    <div>
      ...
    </div>
  </template>
  
  <script>
  export default {
    mounted() {
        window.addEventListener('click', (evt) => {
          this.handleClickEvent(evt)
        })
    },
    destroyed() {
      //   window.removeEventListener('click', ????);
    },
    methods: {
      handleClickEvent(evt) {
        // do stuff with (evt) 
      },
    },
  }
  </script>
  

I have a Vue2 ponent which contains an added eventListener i created on mounted. I was wondering how do i properly remove this listener when the ponent is destroyed?

<template>
    <div>
      ...
    </div>
  </template>
  
  <script>
  export default {
    mounted() {
        window.addEventListener('click', (evt) => {
          this.handleClickEvent(evt)
        })
    },
    destroyed() {
      //   window.removeEventListener('click', ????);
    },
    methods: {
      handleClickEvent(evt) {
        // do stuff with (evt) 
      },
    },
  }
  </script>
  
Share Improve this question edited Dec 8, 2022 at 22:54 Nikola Pavicevic 23.5k9 gold badges29 silver badges51 bronze badges asked Jan 15, 2022 at 23:56 JokerMartiniJokerMartini 6,14712 gold badges102 silver badges221 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

You have to keep a reference to the registered click handler, in order to be able to remove it later:

mounted() {
  this.clickHandler = () => { ... };
  window.addEventListener('click', this.clickHandler);
}

beforeDestroy() {
  window.removeEventListener('click', this.clickHandler);
}

However, you seem to already have this function defined in the ponent. It's named handleClickEvent. So there's no reason to create an arrow function wrapper around it. You can use it directly:

mounted() {
  window.addEventListener('click', this.handleClickEvent);
}

beforeDestroy() {
  window.removeEventListener('click', this.handleClickEvent);
}

Another neat feature available in vue2 (and, sadly, not in vue3) is to dynamically register a hook, which allows adding and removing the handler in mounted(), without the need of keeping a reference to it in the ponent:

mounted() {
  const handler = () => { ... }; // local variable
  window.addEventListener('click', handler);
  this.$once('hook:beforeDestroy',
    () => window.removeEventListener('click', handler)
  );
}

https://v2.vuejs/v2/guide/ponents-edge-cases.html#Programmatic-Event-Listeners

You can use this.$el for whole ponent and destroy event like you created it:

Vue.ponent('Child', {
  template: `
    <div class="child">
      click for event
    </div>
  `,
  mounted() {
    this.$el.addEventListener('click', (evt) => {
      this.handleClickEvent(evt)
    })
  },
  beforeDestroy() {
    console.log('distroyed')
    this.$el.removeEventListener('click', (evt) => {
      this.handleClickEvent(evt)
    })
  },
  methods: {
    handleClickEvent(evt) {
      console.log(evt.currentTarget)
      // do stuff with (evt) 
    },
  },
})


new Vue({
  el: "#demo",
  data() {
    return {
      show: true
    }
  },
  methods: {
    toggleShow() {
      this.show = !this.show
    }
  }
})
.child {
  height: 150px;
  width: 200px;
  background: goldenrod;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div>
    <button @click="toggleShow">mount/unmount ponent</button>
    <Child v-if="show" />
  </div>
</div>

本文标签: javascriptHow to remove event listener from Vue ComponentStack Overflow