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

javascript - Using Vue to count up by seconds - Stack Overflow

programmeradmin3浏览0评论

I'm creating a small timer Vue component. A user needs to be able to start and stop that timer. Here's my component thus far:

<template>
    <div>
        <a class="u-link-white" href="#" @click="toggleTimer">
            {{ time }}
        </a>
    </div>
</template>

<script>
    export default {
        props: ['order'],
        data() {
            return {
                time: this.order.time_to_complete,
                isRunning: false,
            }
        },
        methods: {
            toggleTimer() {
                var interval = setInterval(this.incrementTime, 1000);
                if (this.isRunning) {
                    //debugger
                    clearInterval(interval);
                    console.log('timer stops');
                } else {
                    console.log('timer starts');
                }
                this.isRunning = (this.isRunning ? false : true);
            },
            incrementTime() {
                this.time = parseInt(this.time) + 1;
            },
        }
    }
</script>

I'm toggling the isRunning variable to determine whether the timer is running or not. On first click (the play), the timer begins and increments successfully.

However, on the second click (the pause), the isRunning var toggles back to off, but clearInterval(this.incrementTime) is not clearing the interval and pausing the timer. When I insert that debugger, and manually hit clearInterval(interval) via the console, it returns undefined.

Does anybody have any insight on how I've formatted my component incorrectly?

I'm creating a small timer Vue component. A user needs to be able to start and stop that timer. Here's my component thus far:

<template>
    <div>
        <a class="u-link-white" href="#" @click="toggleTimer">
            {{ time }}
        </a>
    </div>
</template>

<script>
    export default {
        props: ['order'],
        data() {
            return {
                time: this.order.time_to_complete,
                isRunning: false,
            }
        },
        methods: {
            toggleTimer() {
                var interval = setInterval(this.incrementTime, 1000);
                if (this.isRunning) {
                    //debugger
                    clearInterval(interval);
                    console.log('timer stops');
                } else {
                    console.log('timer starts');
                }
                this.isRunning = (this.isRunning ? false : true);
            },
            incrementTime() {
                this.time = parseInt(this.time) + 1;
            },
        }
    }
</script>

I'm toggling the isRunning variable to determine whether the timer is running or not. On first click (the play), the timer begins and increments successfully.

However, on the second click (the pause), the isRunning var toggles back to off, but clearInterval(this.incrementTime) is not clearing the interval and pausing the timer. When I insert that debugger, and manually hit clearInterval(interval) via the console, it returns undefined.

Does anybody have any insight on how I've formatted my component incorrectly?

Share Improve this question asked Dec 22, 2017 at 16:27 Cameron ScottCameron Scott 1,3062 gold badges20 silver badges38 bronze badges 1
  • 1 You'll need to store the value returned from setInterval somewhere. Right now, you declare a variable for it, but that goes out of scope as soon as the function ends. You'll want something like this.interval = setInterval(...) and clearInterval(this.interval). Also, don't create the interval every time; just create it when it's not running and clear it when it is. – Bert Commented Dec 22, 2017 at 16:33
Add a comment  | 

2 Answers 2

Reset to default 15

Here is a working example covering the concepts I mentioned in the comment above. This is not an exact implementation of your component, just an example to show you how it could work.

console.clear()
new Vue({
  el: "div",
  data() {
    return {
      time: 0,
      isRunning: false,
      interval: null
    }
  },
  methods: {
    toggleTimer() {
      if (this.isRunning) {
        clearInterval(this.interval);
        console.log('timer stops');
      } else {
        this.interval = setInterval(this.incrementTime, 1000);
      }
      this.isRunning = !this.isRunning
    },
    incrementTime() {
      this.time = parseInt(this.time) + 1;
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div>
  <a class="u-link-white" href="#" @click="toggleTimer">
    {{ time }}
   </a>
</div>

<template>
    <div>
        <a class="u-link-white" href="#" @click="toggleTimer">
            {{ time }}
        </a>
    </div>
</template>

<script>
    export default {
        props: ['order'],
        data() {
            return {
                time: this.order.time_to_complete,
                isRunning: false,
                interval: undefined // store the interval here
            }
        },
        methods: {
            toggleTimer() {

                if (this.isRunning) {
                    clearInterval(this.interval);
                    console.log('timer stops');
                } else {
                    this.interval = setInterval(this.incrementTime, 1000);
                    console.log('timer starts');
                }
                this.isRunning = !this.isRunning; // better to read
            },
            incrementTime() {
                this.time = parseInt(this.time) + 1;
            },
        }
    }
</script>

Without further testing i think that your first interval just never stops because the pointer to it is just in function scope. Thats why i removed interval into the data object, because so it is available when the methoded gets called the second time. I hope it helps

发布评论

评论列表(0)

  1. 暂无评论