Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

david001's avatar

Vue js time countdown

Hi , i'm new to vue js and want to make minute and second timer and want to alert when time reaches zero. This is so far i have done.


<template>
   {{ countDown }} minutes ramaning
</template>

<script>
    export default {
        data() {
            return {
                countDown : 10
            }
        },
        method: {
            countDownTimer() {
                if(this.countDown > 0) {
                    setTimeout(() => {
                        this.countDown -= 1
                        this.countDownTimer()
                    }, 60000)
                }
            }
        }
        created: {
           this.countDownTimer()
        }
    }
</script>

i want to show output as 10 min 59 sec remaining... and decrementing sec and min.. Please help to display minute and second

0 likes
5 replies
Cruorzy's avatar
<script>
    export default {
        props: {
        
            hours: {
                default: 0
            },
            
            minutes: {
                default: 0
            },
            
            seconds: {
                default: 0
            },
            
            endpoint: {}
            
        },
        
        data() {
            return {
                hoursLeft: this.hours,
                minutesLeft: this.minutes,
                secondsLeft: this.seconds,
            }
        },
        
        methods: {
            
            resetTimer() {
                this.hoursLeft = this.hours;
                this.minutesLeft = this.minutes;
                this.secondsLeft = this.seconds;
            },
            
            zeroPad(input, length) {
                return (Array(length + 1).join('0') + input).slice(-length);
            }
            
        },
        
        mounted() {
            this.resetTimer();
        
            this.$nextTick(function () {
                window.setInterval(() => {
                    if (this.secondsLeft > 0) {
                        this.secondsLeft--;
                    }
                    else if (this.secondsLeft == 0 && this.minutesLeft > 0) {
                        this.secondsLeft = 59;
                        this.minutesLeft--;
                    }
                    else if (this.secondsLeft == 0 && this.minutesLeft == 0 && this.hoursLeft > 0) {
                        this.secondsLeft = 59;
                        this.minutesLeft = 59;
                        this.hoursLeft--;
                    }
                    else {
                        // Timer hits 0 do what you want to do here.
                    }
                },1000);
            })
        },
        computed: {
            timeLeft: function () {
                if (this.hours !== 0) {
                    return this.hoursLeft + ':' + this.zeroPad(this.minutesLeft, 2) + ':' + this.zeroPad(this.secondsLeft, 2);
                }
                else if (this.minutes !== 0) {
                    return this.minutesLeft + ':' + this.zeroPad(this.secondsLeft, 2);
                }
                else {
                    return this.secondsLeft;
                }
            },
        }
        
    }
</script>

<logout-timer minutes="10" seconds="59" ref="logoutTimer" v-on:logout="notAuthenticated = true" inline-template>
    <a class="nav-link" style="width:40px;" v-on:click="resetTimer()">
@{{ timeLeft }}
    </a>
</logout-timer>

This is old code where i had to do something like it, anyways this is from like a while back haven't tested it but you get a idea maybe from it.

Some vue.js guru's should be able to help you.

geraintp's avatar

Something like this ... (untested)

<template>
    <span>Time Remaining: {{remaining}}</span>
</template>

<script>
import {mixin as VueTimers} from 'vue-timers'

export default {
    name: 'countdown',

    timers: {
        updateTime: { time: 1000, autostart: false, repeat: true}
    },

    mixins: [VueTimers],

    data(){
        return {
            remaining_secs: null,
            ends_at: null,
        }
    },

    mounted(){
        this.start();
    },

    methods:{
        start: function () {
            this.ends_at = moment().add(10, 'minutes');
            this.$timer.start('updateTime');
        },

        updateTime: function(){
            const now = moment();
            const ends = moment(this.ends_at);
            const duration = moment.duration(ends.diff(now));

            this.remaining_secs = Math.floor(duration.asSeconds());
        }
    },

    computed:{
        remaining: function () {
            if (!this.remaining_secs) {
                return '10mins';
            }
            const duration = moment.duration(this.remaining_secs, 'seconds');

            const mins = duration.minutes();
            const secs = duration.seconds();

            return mins ? `${mins}mins ${secs}secs` : `${secs}secs`;
        }
    }
}
</script>
SergiuSvet's avatar

Hi there. You can try this one I've made quickly. But please note that it's not a component, but you can easily make one out of this.

new Vue({
  el: "#app",
  data: {
    time: 10, //in seconds
    timer: null,
  },
  methods: {
    decrementOrAlert () {
        if (this.time > 0) {
          this.time--
          return
      }
      
      alert("Time is up!")
      clearInterval(this.timer)
    }
  },
  computed: {
    timeLeft () {
        return `${this.minutes} minutes ${this.seconds} seconds`
    },
    minutes () {
        return String(Math.floor(this.time / 60)).padStart(2, '0')
    },
    seconds () {
        return String(this.time % 60).padStart(2, '0')
    }
  },
  created () {
    this.timer = setInterval(this.decrementOrAlert, 1000)
  }
})

You can see it live here: Fiddle

UPDATE:

I've made a component as well.

JS:

Vue.component("timer", {
    props: {
    value: {
        default: 600
    }
  },
    data() {
    return {
        time: 10, //in seconds
        timer: null,
    }
  },
  methods: {
    decrementOrAlert () {
        if (this.time > 0) {
        this.time--
        return
      }
      
      alert("Time is up!")
      clearInterval(this.timer)
    }
  },
  computed: {
    timeLeft () {
        return `${this.minutes} minutes ${this.seconds} seconds`
    },
    minutes () {
        return String(Math.floor(this.time / 60)).padStart(2, '0')
    },
    seconds () {
        return String(this.time % 60).padStart(2, '0')
    }
  },
  created () {
    this.time = this.value
    this.timer = setInterval(this.decrementOrAlert, 1000)
  },
  template: '<div>{{ timeLeft }} remaining...</div>'
})

new Vue({
  el: "#app",
})

HTML:

<div id="app">
    <!-- timer without value prop -->
    <timer />
    
    <!-- or you can pass a value prop -->
    <timer value="10" />
</div>

Note that the value prop is optional, and defaults to 10 minutes.

You can add more props, like alert message, for example and you can extract the component to a separate .vue file if you want, then import where you need it.

Please or to participate in this conversation.