UNPKG

@cataract6545/tmui

Version:

tm-vuetify是一个新势力由主题驱动的UI组件库,相比其它优势大,组件全,设计趋势紧跟未来。具有主题生成,主题实时切换,暗黑实时切换,lottie动画,图表等新颖功能,tmui TMUI

207 lines (190 loc) 5.36 kB
//倒计时 import { ref, computed, ComputedRef, watch } from 'vue'; interface TimerOptions { totalTime : number; // 总时间,单位毫秒 unit ?: 'ms' | 'ss' | 'mm' | 'hh' | 'dd'; // 时间单位,默认为毫秒 format ?: string; // 时间格式,例如 'yy年dd天 hh时mm分ss秒ms毫秒' } interface FormattedTime { year : number; day : number; hour : number; minute : number; second : number; millisecond : number; } interface TimerState { times : ComputedRef<number>; formattedTime : ComputedRef<(format ?: string) => string>; timeObj : ComputedRef<FormattedTime>; // 新增 timeObj 属性 /**0暂停中,1,运行中,-1从未开始运行过 */ status : ComputedRef<0 | 1 | -1>; start : () => void; stop : () => void; restart : () => void; beforeStart : (call : () => void) => void; timeEnd : (call : () => void) => void; change : (call : (n : number) => void) => void; } /** * 倒计时 * @description 方便计时操作。 */ export function useTimer(options : TimerOptions) : TimerState { const { totalTime, unit = 'ms', format = '' } = options; const times = ref(calculateRemainingTime()); const status = ref<-1 | 0 | 1>(-1); // 'not_started', 'running', 'paused' let _beforeStart = () => { }; let _timeEnd = () => { }; let _change = (n : number) => { }; let timerInterval = 50; // 定时器间隔,单位毫秒 if (unit != 'ms') { timerInterval = 1000 } let timer : NodeJS.Timeout | null = null; let animationFrameId : number | null = null; // 用于存储 requestAnimationFrame 的 ID const timeFomartValue = computed(() => { switch (unit) { case 'ms': return times.value; case 'ss': return Math.floor(times.value / 1000); case 'mm': return Math.floor(times.value / 60000); case 'hh': return Math.floor(times.value / 3600000); case 'dd': return Math.floor(times.value / 86400000); default: return times.value; } }) // #ifndef H5 const start = () => { if (status.value === -1 || status.value === 0) { status.value = 1; _beforeStart(); timer = setInterval(() => { times.value -= timerInterval; if (times.value >= 0) { _change(timeFomartValue.value) } if (times.value <= 0) { times.value = 0; stop(); } }, timerInterval); } }; // #endif // #ifdef H5 const start = () => { if (status.value === -1 || status.value === 0) { status.value = 1; _beforeStart(); console.log(timeFomartValue.value) let lastTime = performance.now() - timerInterval; const update = (currentTime : number) => { const deltaTime = currentTime - lastTime; if (deltaTime >= timerInterval) { lastTime = currentTime; const p = times.value - timerInterval times.value = Number(p.toFixed(0)) if (times.value >= 0) { _change(timeFomartValue.value) } if (times.value <= 0) { times.value = 0; stop(); } } if (status.value === 1) { animationFrameId = requestAnimationFrame(update); } }; animationFrameId = requestAnimationFrame(update); } }; // #endif const stop = () => { if (timer !== null) { clearInterval(timer); timer = null; } if (animationFrameId !== null) { cancelAnimationFrame(animationFrameId); // 取消动画帧请求 animationFrameId = null; } status.value = 0; _timeEnd(); }; const restart = () => { stop(); times.value = calculateRemainingTime(); start(); }; // 监听 totalTime 和 unit 变化,重新计算 times watch([() => options.totalTime, () => options.unit], () => { times.value = calculateRemainingTime(); }); function beforeStart(call : () => void) { _beforeStart = call; } function timeEnd(call : () => void) { _timeEnd = call; } function change(call : (n : number) => void) { _change = call; } function calculateRemainingTime() : number { switch (unit) { case 'ms': return totalTime; case 'ss': return totalTime * 1000; case 'mm': return totalTime * 60000; case 'hh': return totalTime * 3600000; case 'dd': return totalTime * 86400000; default: return totalTime; } }; const formatTime = (time : number) : FormattedTime => { const years = Math.floor(time / (1000 * 60 * 60 * 24 * 365)); // 计算年份 const days = Math.floor((time % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24)); const hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((time % (1000 * 60)) / 1000); const milliseconds = time % 1000; return { year: years, day: days, hour: hours, minute: minutes, second: seconds, millisecond: milliseconds }; }; const formattedTime = computed(() => { let p = formatTime(times.value); return (temForamt ?: string) => { let fat = temForamt || format return fat .replace('yy', String(p.year)) .replace('dd', String(p.day)) .replace('hh', String(p.hour)) .replace('mm', String(p.minute)) .replace('ss', String(p.second)) .replace('ms', String(p.millisecond)) } }); const timeObj = computed(() => formatTime(times.value)); // 计算 timeObj return { times: timeFomartValue, formattedTime, timeObj, status: computed(() => status.value), start, stop, restart, beforeStart, timeEnd, change }; }