Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS with normal JavaScript

I want to add count down timer to my vue component. I have found a script which is written in normal JavaScript. this is my JavaScript file.

var upgradeTime = 7200;
var seconds = upgradeTime;
function timer() {
   var days        = Math.floor(seconds/24/60/60);
   var hoursLeft   = Math.floor((seconds) - (days*86400));
   var hours       = Math.floor(hoursLeft/3600);
   var minutesLeft = Math.floor((hoursLeft) - (hours*3600));
   var minutes     = Math.floor(minutesLeft/60);
   var remainingSeconds = seconds % 60;
   if (remainingSeconds < 10) {
       remainingSeconds = "0" + remainingSeconds;
   }
   document.getElementById('countdown').innerHTML = hours + ":" + minutes + ":" + remainingSeconds;
   if (seconds == 0) {
       clearInterval(countdownTimer);
       document.getElementById('countdown').innerHTML = "Completed";
   } else {
       seconds--;
   }
}
var countdownTimer = setInterval('timer()', 1000);

I stored this as a clock.js in my vue js projects src folder. How do I import this clock.js file to my vue component and get the output.

for this JavaScript code normal way to get output would be something like this

<span id="countdown" class="timer"></span>

But how do I get an output inside a vue component. I'm junior developer and I haven't clear idea about how to use normal JavaScript inside vue. I hope you understand my question. Thank you

like image 969
Pathum Kalhan Avatar asked Mar 09 '18 12:03

Pathum Kalhan


1 Answers

If you really want a simple and straightforward solution, you can simply put all of that within the mounted callback: that is when the component template has been parsed and the DOM constructed, so #countdown should be accessible by then. Read more about lifecycle hooks in VueJS.

Note: However, if you want to really learn how to use VueJS properly, please continue reading on how to create a custom timer component at the end of this answer :) by stuffing everything into the mounted callback, you are missing out the fun part of authoring your first and rather simple VueJS component.

Before we get started, note that there is a mistake when you invoke timer() in your setInterval callback. It should be:

var countdownTimer = setInterval(timer, 1000);

Here is a proof-of-concept example, where you "turkey stuff" all your timer logic into the mounted() callback:

new Vue({
  el: '#app',
  template: '#custom-component',
  mounted: function() {
    var upgradeTime = 7200;
    var seconds = upgradeTime;

    function timer() {
      var days = Math.floor(seconds / 24 / 60 / 60);
      var hoursLeft = Math.floor((seconds) - (days * 86400));
      var hours = Math.floor(hoursLeft / 3600);
      var minutesLeft = Math.floor((hoursLeft) - (hours * 3600));
      var minutes = Math.floor(minutesLeft / 60);
      var remainingSeconds = seconds % 60;
      if (remainingSeconds < 10) {
        remainingSeconds = "0" + remainingSeconds;
      }
      document.getElementById('countdown').innerHTML = hours + ":" + minutes + ":" + remainingSeconds;
      if (seconds == 0) {
        clearInterval(countdownTimer);
        document.getElementById('countdown').innerHTML = "Completed";
      } else {
        seconds--;
      }
    }
    var countdownTimer = setInterval(timer, 1000);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app"></div>

<script type="text/x-template" id="custom-component">
  <div>
    <p>I am a custom component.</p>
    <p>
      My timer:<br />
      <span id="countdown" class="timer"></span>
    </p>
  </div>
</script>

A real ideal solution is to actually create a custom VueJS component for your countdown timer ;) you can do this by simply creating yet another custom component for your timer itself. Some tips and tricks:

  • Use props so that you can pass in a custom time period
  • Remember to use data to make a copy of the time period, since you are decrementing the timer, but you cannot mutate props
  • Use this.$el to refer to your timer component, then you can even make do without the id reference ;)

See proof-of-concept below:

Vue.component('my-timer', {
  template: '#my-timer',
  props: {
    upgradeTime: Number
  },
  data: function () {
    return { seconds: this.upgradeTime }
  },
  methods: {
    timer: function() {
      var days = Math.floor(this.seconds / 24 / 60 / 60);
      var hoursLeft = Math.floor((this.seconds) - (days * 86400));
      var hours = Math.floor(hoursLeft / 3600);
      var minutesLeft = Math.floor((hoursLeft) - (hours * 3600));
      var minutes = Math.floor(minutesLeft / 60);
      var remainingSeconds = this.seconds % 60;
      if (remainingSeconds < 10) {
        remainingSeconds = "0" + remainingSeconds;
      }
      this.$el.innerHTML = hours + ":" + minutes + ":" + remainingSeconds;
      if (this.seconds == 0) {
        clearInterval(countdownTimer);
        this.$el.innerHTML = "Completed";
      } else {
        this.seconds--;
      }
    }
  },
  mounted: function() {
    setInterval(this.timer, 1000);
  },
});

new Vue({
  el: '#app',
  template: '#custom-component'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app"></div>

<script type="text/x-template" id="custom-component">
  <div>
    <p>I am a custom component.</p>
    <p>
      My timer:<br />
      <my-timer upgrade-time="7200"></my-timer>
    </p>
  </div>
</script>

<script type="text/x-template" id="my-timer">
  <span class="timer"></span>
</script>
like image 145
Terry Avatar answered Oct 08 '22 02:10

Terry