'How to make a simple countdown in Vue3?

I've been trying to set-up a simple countdown using Vue3, but I cant make it to work properly. This would be so easy to make in React, but I simply dont understand the logic in Vue (3). So, I've come up with this:

<script>
export default {
    data() {
        return {
            timer: 10,
            interval: ""
        }
    },
    emits: ["start-game"],
    methods: {
        startGame() {
            this.$emit("start-game")

            this.startTimer()
        },
        startTimer() {
            clearInterval(this.interval)

            while(this.timer != 0) {
                this.interval = setInterval(() => {
                    this.timer--
                }, 1000)
            }
        }
    }
}
</script>

You would expect this to work but it creates an infinite loop. Somehow, you cant just use while inside of vue methods. If I remove the while it actually counts down indefinitely, but I need other functions to run once the timer runs out (hits 0). What is the Vue way to handle such things?



Solution 1:[1]

I got the same trouble, I was super happy in react to have react-hook-timer but nothing in vue 3 . So i made it you have 3 main features:

  • timer
  • stopwatch
  • time

For your use case, timer is the one you need, follow these steps:

npm i vue-timer-hook

<script setup>
  import { useTimer } from "vue-timer-hook";

  const timer = useTimer(10 * 1000, false);
  const startGame = () {
    timer.start()
  }
  watchEffect(() => {
    if(timer.isExpired.value) {
        console.warn('IsExpired')
    }
  })
</script>

https://github.com/riderx/vue-timer-hook

Solution 2:[2]

To get this to work I did this in mount():

let this_ = this;  // to make this available as a closure
setInterval(() => {
    this_.$options.timer.bind(this_)();  // methods are available in $options, need to bind `this`
}, 1000)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2