Reputation: 57
Helloo, so I'm making a basic clock in Vue and for some reason with this code I get the initial time value into bazinga
, but once it updates it states that it is undefined. I managed to "make it work" if I define now
and other variables inside the setInterval()
function as well, but this does not seem like a good choice. How come this.bazinga
becomes undefined after the first iteration?
<template>
<div id="clock">
<h2>The time is now</h2>
<p>{{ bazinga }}</p>
</div>
</template>
<style>
</style>
<script>
export default {
data(){
const now = new Date()
const hours = now.getHours()
const minutes = now.getMinutes()
const seconds = now.getSeconds()
return{
bazinga: now
}
},
created() {
setInterval(() => {
console.log(this.bazinga)
this.bazinga = this.now
console.log(this.bazinga)
}, 1000)
},
destroyed() {
clearInterval(this.now)
}
}
</script>
Upvotes: 1
Views: 1150
Reputation: 6909
All your const
variables inside the data
property are not registered as component's data, they are just variables accessible in the data
block.
I assume you want to get an updated new Date()
everytime you call this.now
?
I'd suggest something like that:
<script>
export default {
data(){
return{
now: new Date();
}
},
computed {
hours: function() {
return this.now.getHours()
}
minutes: function() {
return this.now.getMinutes()
},
seconds: function() {
return this.now.getSeconds()
}
},
created() {
setInterval(() => {
this.updateNow()
}, 1000)
},
updateNow() {
this.now = new Date()
}
destroyed() {
clearInterval(this.now)
}
}
</script>
Every call to updateNow()
will get a new Date, and update all the computed as well. :)
Upvotes: 3
Reputation: 135
<template>
<div id="clock">
The Time is Now {{bazinga}}
</div>
</template>
<script>
export default {
data(){
return {
hours: 0,
minutes: 0,
seconds: 0,
hoursDisplay: 0,
secondIterator: 1000,
hourTime: 12,
}
},
mounted() {
this.$options.timer = window.setTimeout(this.updateDateTime, this.secondIterator);
},
destroyed() {
window.clearTimeout(this.$options.timer);
},
methods: {
updateDateTime() {
const now = new Date();
this.hours = now.getHours();
this.minutes = this.zeroPad(now.getMinutes());
this.seconds = this.zeroPad(now.getSeconds());
this.hoursDisplay = this.hours % this.hourTime || this.hours;
this.$options.timer = window.setTimeout(this.updateDateTime, this.secondIterator);
},
zeroPad: function (time) {
return (parseInt(time, 10) >= 10 ? '' : '0') + time;
}
},
computed: {
amPm: function () {
if (this.hours) {
return this.hours >= 12 ? 'PM' : 'AM';
}
},
bazinga: function () {
if (this.amPm) {
return [this.hoursDisplay, this.minutes, this.seconds].join(':') + ' ' + this.amPm;
}
},
}
}
</script>
I made a clock component here, but basically you always want to use data props inside your components and access them with this.someproperty. You can also use watchers or computed properties to return them manipulated like i have done here.
Upvotes: 1