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:{
}
})