Vamos a ver lo sencillo que es crear una cuenta atrás con Vuejs 2 utilizando las funciones setInterval y clearInterval de Javascript junto con MomentJS.

Nosotros lo vamos a hacer por fases para tratar de explicarlo todo detalladamente, pero antes de comenzar, y para hacerlo más sencillo, vamos a instalar moment. yarn add moment Lo primero será crear el componente CountDown.vue para añadir el siguiente código.
<template>
<div>
<div class="card text-white bg-info mb-3" v-if="seconds">
<div class="card-body">
<h2>{{ countdown }}</h2>
</div>
</div>
</div>
</template>
<script>
import * as moment from 'moment';
export default {
name: 'CountDown',
props: {
seconds: {
type: Number,
required: true
}
},
data () {
return {
countdown: null,
expires_in: null,
interval: null,
}
},
mounted () {
this.countdown = moment.utc(this.seconds).format('HH:mm:ss');
this.expires_in = this.seconds;
}
}
</script>
- props: Definimos seconds, será los segundos que tendrá la cuenta regresiva.
- data (): inicializamos algunos datos.
- mounted (): establecemos los datos al inicio del componente con datos válidos.
<template>
<div>
<div class="card text-white bg-info mb-3" v-if="seconds">
<div class="card-body">
<h2>{{ countdown }}</h2>
</div>
</div>
</div>
</template>
<script>
import * as moment from 'moment';
export default {
name: 'CountDown',
props: {
seconds: {
type: Number,
required: true,
}
},
data () {
return {
countdown: null,
expires_in: null,
interval: null,
}
},
mounted () {
this.countdown = moment.utc(this.seconds).format('HH:mm:ss');
this.expires_in = this.seconds;
this._setInterval();
},
methods: {
_setInterval: function() {
this.interval = setInterval(() => {
if (this.expires_in === 0) {
clearInterval(this.interval);
} else {
this.expires_in -= 1;
this.countdown = moment.utc(this.expires_in * 1000).subtract(1, 'seconds').format('HH:mm:ss');
}
}, 1000);
},
}
}
</script>
- _setInterval (): definimos un intervalo que se ejecutará cada segundo para actualizar la cuenta regresiva, asociándola a interval podremos cancelar el intervalo con clearInterval cuando queramos.
- this._setInterval(): hacemos la llamada a _setInterval en el hook mounted.
<template>
<div>
<div class="card text-white bg-info mb-3" v-if="seconds">
<div class="card-body">
<h2>{{ countdown }}</h2>
</div>
</div>
</div>
</template>
<script>
import * as moment from 'moment';
export default {
name: 'CountDown',
props: {
seconds: {
type: Number,
required: true,
}
},
data () {
return {
countdown: null,
expires_in: null,
interval: null,
}
},
mounted () {
this.countdown = moment.utc(this.seconds).format('HH:mm:ss');
this.expires_in = this.seconds;
this._setInterval();
},
destroyed () {
clearInterval(this.interval);
},
methods: {
_setInterval: function() {
this.interval = setInterval(() => {
if (this.expires_in === 0) {
clearInterval(this.interval);
} else {
this.expires_in -= 1;
this.countdown = moment.utc(this.expires_in * 1000).subtract(1, 'seconds').format('HH:mm:ss');
}
}, 1000);
},
}
}
</script>
- destroyed (): en el momento en el que el componente sea destruido eliminamos el intervalo para que no siga trabajando de fondo.
Con todo lo anterior ya tendríamos el componente CountDown listo para utilizar, así que el siguiente código será 100% funcional desde cualquier otro componente.
<template>
<div class="home">
<img src="../assets/logo.png">
<CountDown :seconds="1212" />
<CountDown :seconds="650" />
<CountDown :seconds="320" />
</div>
</template>
<script>
import CountDown from '@/components/CountDown.vue'
export default {
name: 'home',
components: {
CountDown
}
}
</script>
Con este último trozo de código ya tendríamos lista una cuenta atrás con Vuejs 2 completamente funcional, fíjate que le pasamos los segundos para que sea más dinámica.