84 lines
1.5 KiB
Vue
84 lines
1.5 KiB
Vue
<template>
|
|
<div class="countdown">
|
|
<span class="time-unit">{{ formattedTime }}</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
duration: {
|
|
type: Number,
|
|
default: 60
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
timeLeft: this.duration,
|
|
timer: null,
|
|
isExpired: false
|
|
}
|
|
},
|
|
computed: {
|
|
// 将秒数格式化为 HH:MM:SS
|
|
formattedTime() {
|
|
const hours = Math.floor(this.timeLeft / 3600)
|
|
const minutes = Math.floor((this.timeLeft % 3600) / 60)
|
|
const seconds = this.timeLeft % 60
|
|
|
|
// 一位数时前面补零
|
|
const pad = (num) => num.toString().padStart(2, '0')
|
|
|
|
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
|
|
}
|
|
},
|
|
watch: {
|
|
timeLeft(newValue) {
|
|
if (newValue <= 0) {
|
|
this.handleFinish()
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.startTimer()
|
|
},
|
|
beforeUnmount() {
|
|
this.clearTimer()
|
|
},
|
|
methods: {
|
|
startTimer() {
|
|
this.clearTimer()
|
|
this.timer = setInterval(() => {
|
|
this.timeLeft--
|
|
}, 1000)
|
|
},
|
|
clearTimer() {
|
|
if (this.timer) {
|
|
clearInterval(this.timer)
|
|
this.timer = null
|
|
}
|
|
},
|
|
handleFinish() {
|
|
this.isExpired = true
|
|
this.clearTimer()
|
|
this.$emit('finished')
|
|
},
|
|
reset() {
|
|
this.timeLeft = this.duration
|
|
this.isExpired = false
|
|
this.startTimer()
|
|
},
|
|
// 暂停
|
|
pause() {
|
|
this.clearTimer()
|
|
},
|
|
// 继续
|
|
resume() {
|
|
this.startTimer()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
</style> |