I am creating a timer using vue.js and moment.js, I use only minutes and seconds, my code should work, but I do not get the desired result:
var app = new Vue({
el: '#app',
data: {
date: moment(60 * 10 * 1000)
},
computed: {
time: function(){
return this.date.format('mm:ss');
}
},
mounted: function(){
var aa = this.date;
setInterval(function(){
aa.subtract(1, 'seconds');
}, 1000);
}
});
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">{{ time }}</div>
As @Phil pointed out, the issue is caused by reactivity issue. subtract
just update some properties then return orginal object.
So we should have to use one new object to replace old one. (Probably exists one way to use Vue.set
or vm.$set
to update the properties of moment object, hopefully someone can point out.)
Like below demo:
var app = new Vue({
el: '#app',
data: {
date: moment(60 * 10 * 1000)
},
computed: {
time: function(){
return this.date.format('mm:ss');
}
},
mounted: function(){
setInterval(() => {
this.date = moment(this.date.subtract(1, 'seconds'))
}, 1000);
}
});
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">{{ time }}</div>
here is example of count down using VUE with moment
<script>
new Vue({
el: '#app',
data: {
message: 'Current Time:',
currentTime: null },
methods: {
updateCurrentTime: function updateCurrentTime() {
this.currentTime = moment().format('LTS');
} },
created: function created() {var _this = this;
this.currentTime = moment().format('LTS');
setInterval(function () {return _this.updateCurrentTime();}, 1 * 1000);
} });
</script>
<section id="app" class="section">
<h3 class="title is-3 shadow" v-text="message"></h3>
<p class="time shadow" v-text="currentTime"></p>
</section>
<style>
body, html {
width: 100%;
height: 100%;
}
body {
background: -webkit-linear-gradient(LightSteelBlue, LightSalmon);
background: -o-linear-gradient(LightSteelBlue, LightSalmon);
background: -moz-linear-gradient(LightSteelBlue, LightSalmon);
background: linear-gradient(LightSteelBlue, LightSalmon);
}
section.section {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 140px;
background: transparent;
}
h3.is-3, p.time {
color: white;
}
h3.is-3:not(:last-child) {
margin: 0;
padding: 0;
}
.time {
font-size: 7em;
}
.shadow {
text-shadow: 0 0 15px rgba(100, 100, 100, 0.35);
</style>
Countdown component for VueJS with momentjs
here is a reference link
alsi that's example without vue only using moment
// get next Sunday
var nextSunday = moment().day(7).format("YYYY-MM-DDT11:00:00Z");
// make it a moment object again
var event = moment(nextSunday);
// get current time/date
var current = moment();
// get difference between event and current
var diffTime = event.diff(current);
// let moment.js make the duration out of the timestamp
var duration = moment.duration(diffTime, 'milliseconds', true);
// set interval to milliseconds
var interval = 1000;
setInterval(function(){
duration = moment.duration(duration - interval, 'milliseconds');
$('#clock').html(
"<div class=\'days cell\'>"+duration.days()+"<span>days</span></div>" +
"<div class=\'hours cell\'>"+duration.hours()+"<span>hours</span></div>" +
"<div class=\'mins cell\'>"+duration.minutes()+"<span>mins</span></div>" +
"<div class=\'secs cell\'>"+duration.seconds()+"<span>secs</span></div>")
}, interval);
$section-color: #343436;
body {
background-color: #1d1f20;
color: #99999d;
}
body * {
box-sizing: border-box;
}
#clock {
width: 80%;
margin: 10em auto;
text-align: center;
transform: scale(0.8);
}
#clock .cell {
display: inline-block;
width: 80px;
height: 60px;
background-color: #1b1b1c;
position: relative;
border-radius: 5px;
margin-right: 5px;
font-size: 3rem;
padding-top: 2px;
}
#clock .cell span {
position: absolute;
left: 0;
bottom: -30px;
clear: both;
text-align: center;
text-transform: uppercase;
width: 80px;
height: 20px;
font-size: 10px;
}
body {
background-color: #1d1f20;
color: lighten($section-color, 40%);
* {
box-sizing: border-box;
}
}
#clock {
width: 80%;
margin: 10em auto;
text-align: center;
transform: scale(.8);
}
.cell {
display: inline-block;
width: 80px;
height: 60px;
background-color: darken($section-color, 10%);
position: relative;
border-radius: 5px;
margin-right: 5px;
font-size: 3rem;
padding-top: 2px;
color:white;
}
.cell span {
position: absolute;
left: 0;
bottom: -30px;
clear: both;
text-align: center;
text-transform: uppercase;
width: 80px;
height: 20px;
font-size: 10px;
color:white;
}
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js'></script>
<div id="clock"></div>
<div style= "color:white;" id="countdown">
</div>
This is a reactivity issue. Vue isn't going to watch / bind on method calls to your moment
object.
You'll need to assign the result of the date manipulation back to your date
property. You also need to clone the moment
instance so it appears as a new value and not the same instance.
setInterval(() => {
this.date = this.date.clone().subtract(1, 'seconds')
}, 1000)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With