Timer
Template
HTML
<template>
<label>
Elapsed Time: <progress :value="progressRate"></progress>
</label>
<div>{{ (elapsed / 1000).toFixed(1) }}s</div>
<div>
Duration: <input type="range" v-model="duration" min="1" max="30000">
{{ (duration / 1000).toFixed(1) }}s
</div>
<button @click="reset">Reset</button>
</template>
<template>
<label>
Elapsed Time: <progress :value="progressRate"></progress>
</label>
<div>{{ (elapsed / 1000).toFixed(1) }}s</div>
<div>
Duration: <input type="range" v-model="duration" min="1" max="30000">
{{ (duration / 1000).toFixed(1) }}s
</div>
<button @click="reset">Reset</button>
</template>
Composition API
It's an example for <scipt setup>
.
JavaScript
import { ref, onUnmounted, computed } from 'vue'
const duration = ref(15 * 1000)
const elapsed = ref(0)
let lastTime
let handle
const update = () => {
elapsed.value = performance.now() - lastTime
if (elapsed.value >= duration.value) {
cancelAnimationFrame(handle)
} else {
handle = requestAnimationFrame(update)
}
}
const reset = () => {
elapsed.value = 0
lastTime = performance.now()
update()
}
const progressRate = computed(() =>
Math.min(elapsed.value / duration.value, 1)
)
reset()
onUnmounted(() => {
cancelAnimationFrame(handle)
})
import { ref, onUnmounted, computed } from 'vue'
const duration = ref(15 * 1000)
const elapsed = ref(0)
let lastTime
let handle
const update = () => {
elapsed.value = performance.now() - lastTime
if (elapsed.value >= duration.value) {
cancelAnimationFrame(handle)
} else {
handle = requestAnimationFrame(update)
}
}
const reset = () => {
elapsed.value = 0
lastTime = performance.now()
update()
}
const progressRate = computed(() =>
Math.min(elapsed.value / duration.value, 1)
)
reset()
onUnmounted(() => {
cancelAnimationFrame(handle)
})
If you are using the Option API style with setup()
, you need to return certain variables and computed properties:
JavaScript
export default {
setup() {
return {
duration,
elapsed,
progressRate,
reset
}
}
}
export default {
setup() {
return {
duration,
elapsed,
progressRate,
reset
}
}
}
Options API
JavaScript
export default {
data() {
return {
duration: 15 * 1000,
elapsed: 0
}
},
created() {
this.reset()
},
unmounted() {
cancelAnimationFrame(this.handle)
},
computed: {
progressRate() {
return Math.min(this.elapsed / this.duration, 1)
}
},
methods: {
update() {
this.elapsed = performance.now() - this.lastTime
if (this.elapsed >= this.duration) {
cancelAnimationFrame(this.handle)
} else {
this.handle = requestAnimationFrame(this.update)
}
},
reset() {
this.elapsed = 0
this.lastTime = performance.now()
this.update()
}
}
}
export default {
data() {
return {
duration: 15 * 1000,
elapsed: 0
}
},
created() {
this.reset()
},
unmounted() {
cancelAnimationFrame(this.handle)
},
computed: {
progressRate() {
return Math.min(this.elapsed / this.duration, 1)
}
},
methods: {
update() {
this.elapsed = performance.now() - this.lastTime
if (this.elapsed >= this.duration) {
cancelAnimationFrame(this.handle)
} else {
this.handle = requestAnimationFrame(this.update)
}
},
reset() {
this.elapsed = 0
this.lastTime = performance.now()
this.update()
}
}
}