最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to remove event listener from Vue Component - Stack Overflow

programmeradmin1浏览0评论

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>

发布评论

评论列表(0)

  1. 暂无评论