DEV Community

Rachel
Rachel

Posted on

Timer Component for Vue.js

"My recipe for dealing with anger and frustration: set the kitchen timer for twenty minutes, cry, rant, and rave, and at the sound of the bell, simmer down and go about business as usual." - Phyllis Diller

Timers are used often to generate a sense of urgency. You'll see them used on landing pages or product pre-launch pages. Here's a simple timer to incorporate into your next Vue project.

Here's a preview:

Template

The template is quite simple. To create the timer, you need an element to display the countdown. I kept it simple, enclosing it in a p tag, but there's plenty of ways to add complexity depending on your design requirements.

  <p class="text-4xl text-black" v-if="currentTime">
      {{
        currentTime
          ? `${currentTime.days}:${("0" + currentTime.hours).slice(-2)}:${(
              "0" + currentTime.minutes
            ).slice(-2)}:${("0" + currentTime.seconds).slice(-2)}`
          : ""
      }}
    </p>
    <p v-if="!currentTime">
      Time's Up!
    </p>
Enter fullscreen mode Exit fullscreen mode

Styles

For simplicity, I've used Tailwind CSS for styling.

Script

Props & Computed Values

This component takes in 2 props: deadline and speed. The deadline prop is the date for which you are counting down. The speed prop is the amount of time that passes before the numbers change. This is perhaps optional, as the default is to count down every second.

Update

In the updated version, days, hours, minutes, and seconds have been moved to computed properties.

A filter is also used to format the value.

Data

There's only 1 data value - currentTime which keeps track of the current time to display.

Methods

countdown() is the primary method. It first gets called when the component is mounted, then calls itself every second. In this method, the time is parsed into different units of time, stored in currentTime, which is then used to display the timer.

In the updated version, countdown() is much simpler, setting a new currentTime every second.

The original codepen is below, followed by an updated version.

Update

Thanks to a suggestion by stefanovualto, I've refactored the code using computed properties and filters.

The HTML is much simpler in this version, as I've moved the formatting into a filter:

The final js is also easier to read, I think.

And a Github Gist for the Single Page Component:

Code reviews welcome. Let me know if I can do something better.

Next Steps

I kept this implementation simple, but I envision adding layers of design complexity to this countdown timer at a later date.

Resources

I can't take all the credit for this.

I learned a lot from Yaphi Berhanu's article published on Sitepoint about building a Javascript Timer.

Discussion (7)

Collapse
robole profile image
Rob OLeary

It's possible now to have single-file vue components in Codepen, might simplify your post to include the code from your gist in there instead!

Collapse
rachel_cheuk profile image
Rachel Author

This is good to know! Thanks Rob!

Collapse
stefanovualto profile image
stefanovualto

Hi Rachel,
Have envisaged to use a computed property to format the currentTime in the template?

As a detail, personally I would use a setInterval instead of multiple setTimeout.

Collapse
rachel_cheuk profile image
Rachel Author

Thanks for the suggestion Stefan! It never occurred to me; it's certainly a more vue approach!

I've added a second codepen with the code refactored into computed methods. I think it's much easier to read now. Thank you for the suggestion!

Collapse
davydocsurg profile image
David Chibueze

nice one

Collapse
martincomito profile image
Martín Comito

Great article, thanks for the contribution!