import { ref, watch } from 'vue' import { formatNumber } from '../../../../utils' import type { SetupContext } from 'vue' import type { CountDownEmits, CountDownProps } from '../count-down' const SECOND = 1 const MINUTE = 60 * SECOND const HOUR = 60 * MINUTE const DAY = 24 * HOUR export const useCountDown = ( props: CountDownProps, emits: SetupContext['emit'] ) => { // 当前倒计时时间 let time = 0 // 时间定义 const day = ref('') const hour = ref('') const minute = ref('') const second = ref('') // 将时间戳转换为对应的时间 const splitCountDownData = () => { const { showDay, showHour, showMinute, showSecond, autoHideDay } = props const _day = Math.floor(time / DAY) // 如果不显示天数则将天的时间加到小时上,后面的分钟和秒如此累加 const _hour = showDay ? Math.floor((time % DAY) / HOUR) : Math.floor(time / HOUR) const _minute = Math.floor((time % HOUR) / MINUTE) const _second = Math.floor(time % MINUTE) // 判断是否自动隐藏天数 if (!showDay || (autoHideDay && _day === 0)) day.value = '' else day.value = formatNumber(_day, 4) hour.value = showHour ? formatNumber(_hour, 4) : '' minute.value = showMinute ? formatNumber(_minute) : '' second.value = showSecond ? formatNumber(_second) : '' } // 倒计时定时器 let countDownTimer: ReturnType | null = null // 开始倒计时 const startCountDown = () => { // 如果倒计时时间为0,重新设置倒计时时间 if (time <= 0) time = props.time else { // 先渲染一次 time-- } // 先停止之前的倒计时 stopCountDown() emits('start') // 开始倒计时 countDownTimer = setInterval(() => { if (time < 0) { stopCountDown() emits('end') return } splitCountDownData() time-- }, 1000) } // 停止倒计时 const stopCountDown = () => { if (countDownTimer) { clearInterval(countDownTimer) countDownTimer = null } } // 重置定时器 const resetCountDown = () => { stopCountDown() time = props.time splitCountDownData() } watch( () => props.time, (_time) => { resetCountDown() // 自动开始倒计时 if (props.autoStart && _time > 0) { startCountDown() } }, { immediate: true, } ) return { day, hour, minute, second, startCountDown, stopCountDown, resetCountDown, } }