[Vuejs]-Countdown timer in vue3 composition API / script setup

0👍

Here’s a vue3 way of doing it with the reactive store state.

//store.js
import { reactive, readonly } from 'vue'

const state = reactive({
  countdownPaused: false
})

function toggleCountdownPlayPause() {
  state.countdownPaused = !state.countdownPaused
}

export const store = readonly({
  state,
  toggleCountdownPlayPause
})

//main.js
import { createApp } from 'vue'
import store from './store'
import App from './App.vue'

const app = createApp(App)
app.use(store)
app.config.globalProperties.$store=store
app.mount("#app")
// components/Timer.vue
<template>
  <b>
    <span>{{ cowntdown }}</span>
  </b>
</template>
<script>
import store from '../../store'
export default {
  data() {
    return {
      store,
      timerCountdown: 120,
      timeout: null
    }
  },
  watch: {
    paused(isPaused) {
      if (!isPaused) {
        this.timerCountdown--
      } else {
        clearTimeout(this.timeout)
      }
    },
    timerCount: {
      handler(value) {
        if (value > 0 && !this.paused) {
          this.timeout = setTimeout(() => this.timerCountdown--, 1000)
        }
      },
      immediate: true
    }
  },
  computed: {
    paused() {
      return store.state.countdownPaused
    },
    formattedCountdown() {
        const minutes = Math.floor(this.timerCount / 60) > 0 ? Math.floor(this.timerCount / 60 ) : "00"
        const seconds = this.timerCount % 60 > 9 ? this.timerCount % 60 : "0" + [this.timerCount % 60]
        return `${minutes}:${seconds}`
    }
  }
</script>
// components/TimerPlayPauseButton.vue
<template>
  <button :class="{'paused':paused}" @click="togglePlayPause"></button>
  </template>
  <script>
  import { store } from '../../store'
 
  export default {
    data() {
      return {
        store,
        paused: store.state.countdownPaused
      }
    },
    methods: {
      togglePlayPause(e) {
        this.store.toggleCountdownPlayPause()
      }
    }
  }
</script>
<style>
.paused:after {
  content: "ll"
}
//App.vue
<template><div><timer /><timer-play-pause-button /></div></template>
<script>
import Timer from './components/Timer.vue'
import TimerPlayPauseButton from './components/TimerPlayPauseButton.vue'

export default {
   components: {
     'timer': Timer,
     'timer-play-pause-button': TimerPlayPauseButton
   }
}

Leave a comment