I have a mixin that returns remaining time in this format HH:mm:ss
.
Vue.mixin({
methods: {
remainingTime(){
// some calculations based on current time and given time
return timeLeft.toString();
}
....
in component, I call the mixin to get the time
export default {
....
data() {
return {
timeLeft: this.remainingTime(),
....
and in my template I call it {{timeLeft}}
which returns something like 01:20:33
but I want to display this value as a countdown. So the moment it loads on the page, start counting down 1 second.
I tried to use a watcher but it doesnt work:
watch: {
timeLeft: {
handler(value) {
if (value) {
setInterval(() => {
this.timeLeft;
}, 1000);
}
},
immediate: true,
},
},
CodePudding user response:
You can use mod (%) to extract hour minutes and date.
Code taken from article at bottom of this post. Run the setInterval on mounted
or whenever you get data for deadline date time
let countDownDate = new Date("Jan 01, 2023 00:00:00").getTime(); // The deadline
let x = setInterval(() => {
let now = new Date().getTime();
let distance = countDownDate - now;
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((distance % (1000 * 60)) / 1000);
console.log(days "d " hours "h " minutes "m " seconds "s"); // Countdown output
if (distance < 0) {
clearInterval(x);
console.log("Too late!") // Text at the end of the countdown
}
}, 1000)
You can check it here https://beetrootacademy.se/blog/front-end-development/js-countdown-timer-14-lines
CodePudding user response:
Keep time with a numeric value. Present time with a string value. The watcher's job is to notice changes in the numeric time and convert it to a string.
It's definitely not a watcher's job to setInterval(). You'll end up starting new timers willy nilly.
Vue.config.productionTip = false;
Vue.config.devtools = false;
var app = new Vue({
el: '#app',
data: {
timeLeft: 0,
timeLeftString: '',
timer: null
},
watch: {
timeLeft: function (val) {
const timeZero = moment("1900-01-01 00:00:00");
this.timeLeftString = timeZero.add(val, 'seconds').format("HH:mm:ss")
},
},
mounted() {
this.timeLeft = 63;
this.timer = setInterval(() => {
if (this.timeLeft <= 0) {
clearInterval(this.timer);
alert('Done');
} else {
this.timeLeft--
}
}, 1000)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>
{{ timeLeftString }}
</h1>
</div>