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

javascript - Vue.js Time Counter - Stack Overflow

programmeradmin2浏览0评论

I'm trying to build a timer using Vue.js and I want it to output the time left.

new Vue({
    el: "#app",
    data: {
        timer: 25,
        message2: "",
        counter: false,
        interval: null
    },
    methods: {
        startTimer() {
            this.interval = setInterval(this.countDown(), 1000);
        },
        countDown() {
            if (this.counter === false) {
                var n = this.timer;
                this.counter = true;
            } else if (n > 0) {
                n -= 1;
                this.message2 = "You have " + n + "seconds left.";
            } else {
                clearInterval(this.interval);
                this.counter = false;
                this.message2 = "Your time is up!"
            }
        },

But I cannot get the message2 updated every time Interval runs the function countDown(). Actually it doesn't run the function every second but only once.

I'm trying to build a timer using Vue.js and I want it to output the time left.

new Vue({
    el: "#app",
    data: {
        timer: 25,
        message2: "",
        counter: false,
        interval: null
    },
    methods: {
        startTimer() {
            this.interval = setInterval(this.countDown(), 1000);
        },
        countDown() {
            if (this.counter === false) {
                var n = this.timer;
                this.counter = true;
            } else if (n > 0) {
                n -= 1;
                this.message2 = "You have " + n + "seconds left.";
            } else {
                clearInterval(this.interval);
                this.counter = false;
                this.message2 = "Your time is up!"
            }
        },

But I cannot get the message2 updated every time Interval runs the function countDown(). Actually it doesn't run the function every second but only once.

Share Improve this question edited Jun 9, 2017 at 9:31 Yanek Yuk asked Jun 9, 2017 at 9:22 Yanek YukYanek Yuk 743 silver badges11 bronze badges 3
  • 1 You're executing undefined in setInterval because you're calling your countDown method which doesn't return a function. – Wabbitseason Commented Jun 9, 2017 at 9:34
  • I'm not sure that I understand. I've always thought of methods as functions. – Yanek Yuk Commented Jun 9, 2017 at 9:37
  • this.interval = setInterval(this.countDown, 1000); remove the () from the function. setInterval is expecting a function as 1st parameter. That means you pass it a function reference like this.countDown or declare an anonymous function like function() { //dostuff}. Check this out for further information about function calls/references: stackoverflow./questions/15886272/… – xetra11 Commented Jun 9, 2017 at 9:42
Add a ment  | 

2 Answers 2

Reset to default 4

You should pass a function to setInterval, but since you execute this.countDown immediatly, you are passing the result of that call to setInterval:

startTimer() {
  this.interval = setInterval(this.countDown(), 1000);
}

to pass the function instead of calling it, leave out the ()

startTimer() {
  this.interval = setInterval(this.countDown, 1000);
}

also, I fixed some mistakes in countdown() (e.g. defining n in the if branch, but using it in the else if, so it's undefined there, or only changing the local n, which would not change this.timer ...)

countDown() {
  var n = this.timer
  if (!this.counter) {
    this.counter = true;
  } else if (n > 0) {
    n = n - 1
    this.timer = n
    this.message2 = "You have " + n + "seconds left."
  } else {
    clearInterval(this.interval);
    this.counter = false
    this.message2 = "Your time is up!"
  }
},

As others have pointed out, you need to pass your function to setInterval, not invoke it and pass its return value.

Furthermore, when you execute the statement n = this.timer, you are invoking the getter that Vue set up on this.timer and copying the very unmagical number 25 to your variable n. n then goes out of scope when the function returns and your copy of 25 is lost. The next time your function runs (another second later) n is undefined. This results in your else clause clearing the interval. Your elseif clause never runs.

I think the smallest change to make your code work would be to promote n to live in your data: add n: undefined, to your data:{}, so that it can be tracked by Vue, then replace all your uses of n with this.n.

Once you've got that working, I'd remend simplifying some things:

  • setting this.n = this.timer should probably be done in startTimer
  • if you set this.interval = undefined when you clear your interval, this.counter bees redundant, because you can just check if this.interval is truthy
  • you can turn message2 into a "puted"
  • you can add an if clause to startTimer to prevent a second interval from being added if there's already one active (e.g. if someone clicks a "start timer" button twice before the timer runs down)
发布评论

评论列表(0)

  1. 暂无评论