Vue.js destroy a setInterval running inside a component

10,057

Solution 1

There might be two things happening here depending on if you are calling countdown or not:

1. countdown is not called

countdown(index, exp) needs to be defined in the created hook such as below. Furthermore, a method foo() should be bound to this interval for the expected functionality.

  created: function(){
      this.counterInterval =  setInterval(
        function()
        {
          this.foo();
        }.bind(this), 500);
    return this.foo();
  },
  destoyed: function(){
    clearInterval( this.counterInterval )
  },

2. countdown is called properly but the component is actually not getting destroyed

If the error is actually a misunderstanding on what it means to "destroy" the component, such that the component is not getting destroyed, the same code as above can be used, but a data prop of isShowing: true bounded within the JSX will solve the problems.

Just do a v-if check on isShowing and then do an event listener if the element is in view. If the element is in view, then we have isShowing===true. else, false.

Solution 2

In vue3 destroy() and beforeDestroy() has been deprecated.

Use unmount() or beforeUnmount() instead.

beforeUnmount(){
    clearInterval(this.counters);
}

Solution 3

You should use beforeDestroy hook instead of destroyed

For reference on vue lifecycle check out https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

Share:
10,057
Uncoke
Author by

Uncoke

It's me! TA-DA!

Updated on June 23, 2022

Comments

  • Uncoke
    Uncoke almost 2 years

    In my SPA made with VUE I have a component running a recursive few of setInterval functions (it's a countdown). I noticed the countdown continue in the background when I switch view to another component, but I prefer to destroy the setInterval.

    I tried using a global data having the countdowns and then destroy it on destroyed hook but it doesn't work.

    Here my code:

        data: function () {
            return {
                counters: ""
            }
        }),
    
       methods: {
         countdown(index, exp) {
            ...
              this.counters = setInterva()
            ...
            },
       },
    
       destroyed(){
            console.log(this.counters); // returns a progressive integer
            clearInterval(this.counters);
            console.log(this.counters); // returns same integer
            this.counters = 0;
            console.log("destroyed");
        } 
    

    But in the console I got:

    destroyed

    app.js:64433 0

    app.js:64398 Missing counter_1 . <--- which means counter is still running

    Thanks for any suggestion!