<template>
<div class="countdown-box">
<span>{{ formatTime }}</span>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
let formatTime = ref('');
const props = defineProps({
totalTime: Number,
interval: {
type: Number,
default: 1000
},
})
watch(() => props.totalTime, (newVal, oldVal) => {
totalTime = newVal;
stopCountDown()
startCountDown()
})
const secondToTimeStr = (t: number, type: any) => {
let timeStr1 = '', timeStr2 = '', timeStr3 = '';
if (type == 0) {
timeStr1 = ':'; timeStr2 = ':'; timeStr3 = ':';
}else if (type == 1) {
timeStr1 = '小时'; timeStr2 = '分'; timeStr3 = '秒'
};
if (!t) return;
if (t < 60) return "00" + timeStr2 + ((i = t) < 10 ? "0" + i : i);
if (t < 3600) return "" + ((a = parseInt(t / 60)) < 10 ? "0" + a : a) + timeStr2 + ((i = t % 60) < 10 ? "0" + i : i);
if (3600 <= t) {
var a, i, e = parseInt(t / 3600);
if (type == 0) {
return (e < 10 ? "0" + e : e) + timeStr1 + ((a = parseInt(t % 3600 / 60)) < 10 ? "0" + a : a) + timeStr2 + ((i = t % 60) < 10 ? "0" + i : i);
} else if (type == 1) {
return (e < 10 ? "0" + e : e) + timeStr1 + ((a = parseInt(t % 3600 / 60)) < 10 ? "0" + a : a) + timeStr2 + ((i = t % 60) < 10 ? "0" + i : i) + timeStr3;
}
}
}
const interval = props.interval;
let totalTime = props.totalTime
let count = 0
let firstTimer = new Date().getTime();
let timer: NodeJS.Timeout | null | undefined;
const func = () => {
count++
let delaytimer = new Date().getTime() - (interval * count + firstTimer)
let nextTimer = interval - delaytimer
if (nextTimer < 0) {
nextTimer = 0
}
totalTime -= interval / 1000;
console.log(`延迟:${delaytimer}ms, 下一次执行:${nextTimer}ms, 还剩:${totalTime}ms。`)
formatTime.value = secondToTimeStr(totalTime, 0);
if (totalTime <= 0) {
formatTime.value = "已结束";
clearTimeout(timer)
} else {
timer = setTimeout(func, nextTimer)
}
}
const stopCountDown = () => {
clearTimeout(timer)
}
const startCountDown = () => {
if (totalTime == 0) {
formatTime.value = "已结束";
} else if (totalTime <= -1) {
formatTime.value = "未开始";
} else {
count = 0;
firstTimer = new Date().getTime();
timer = setTimeout(func, interval)
}
}
startCountDown();
defineExpose({
stopCountDown,
startCountDown
})
onBeforeUnmount(() => {
clearTimeout(timer);
})
</script>
<style lang="less" scoped>
.countDown-box {
display: flex;
justify-content: center;
position: absolute;
color: white;
font-size: 18px;
left: 430px;
top: 25px;
span {
color: rgb(255, 255, 0);
font-weight: 500;
font-size: 18px;
width: 50px;
}
}
</style>