JSFiddle - React, Tailwind, and code Playground

by shanemendez

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
    <template id="interval">
        <div class="interval">    
            <span is="span">{{timer.time}}</span>
            <span is="span">{{timer.desc}}</span>
        </div>
    </template>
    <div id="app">
        <div>{{timeElapsed}}</div>
        <interval 
            v-for="timer in timers"
            :timer="timer"
            :key="timer.id"
        ></interval>
        <button
            id="start"
            v-if="!timer"
            @click="start"
        >Start Timer</button>
        <button
            id="stop"
            v-if="timer"
            @click="stop"
        >Stop Timer</button>
        
        
    </div>
</body>
<script src="main.js"></script>
</html>

Vue

Vue.component('interval', {
    props: ['timer'],
    methods: {
        //time elapsed since last update in milliseconds
        update(elapsed){
            this.timer.time -= elapsed 
        }
    },
    template: '#interval'
  })
vue = new Vue({
    el: "#app",
    data: {
        active: 0,
        timeElapsed: 0,
        timer: null,
        timers: [
            {id:0, time:1000, desc:"pushups"},
            {id:1, time:1000, desc:"situps"},
            {id:2, time:1000, desc:"planks"},
            {id:3, time:100000, desc:"cry"},
        ],
    },
    computed:{
        activeTimer(){
            return this.timers[this.active]
        }
    },
    methods: {
        start(){
            interval = 100
            this.timer = setInterval(()=>this.update(interval), interval)
        },
        stop(){
            clearInterval(this.timer)
            this.timer = null
            this.timeElapsed = 0
        },
        //interval in millis
        update(interval){
           this.activeTimer.time =  Math.max(this.activeTimer.time -= interval,0)
           this.timeElapsed += interval
            if (this.activeTimer.time == 0) this.nextTimer()
        },
        nextTimer(){
            this.active += 1
            if(!this.activeTimer){
                this.active -= 1
                this.stop()
            }

        }
    },
    watch:{
    }
})