useCountdown Composable
Reactive countdown timer with start/pause/reset functionality
Code
import { ref, onUnmounted } from 'vue';
interface CountdownReturn {
seconds: Ref<number>;
minutes: Ref<number>;
hours: Ref<number>;
isRunning: Ref<boolean>;
start: () => void;
pause: () => void;
reset: (newDuration?: number) => void;
}
export function useCountdown(initialDuration = 60): CountdownReturn {
const duration = ref(initialDuration);
const remainingTime = ref(initialDuration);
const isRunning = ref(false);
let intervalId: ReturnType<typeof setInterval> | null = null;
// Calculate formatted time
const seconds = ref(remainingTime.value % 60);
const minutes = ref(Math.floor((remainingTime.value % 3600) / 60));
const hours = ref(Math.floor(remainingTime.value / 3600));
const updateFormattedTime = () => {
seconds.value = remainingTime.value % 60;
minutes.value = Math.floor((remainingTime.value % 3600) / 60);
hours.value = Math.floor(remainingTime.value / 3600);
};
const tick = () => {
__TOKEN_24__ (remainingTime.value <= 0) {
pause();
return;
}
remainingTime.value--;
updateFormattedTime();
};
const start = () => {
__TOKEN_27__ (isRunning.value || remainingTime.value <= 0) return;
isRunning.value = true;
intervalId = setInterval(tick, 1000);
};
const pause = () => {
__TOKEN_30__ (!isRunning.value) return;
isRunning.value = false;
__TOKEN_32__ (intervalId) clearInterval(intervalId);
};
const reset = (newDuration?: number) => {
pause();
duration.value = newDuration || initialDuration;
remainingTime.value = duration.value;
updateFormattedTime();
};
// Initial format
updateFormattedTime();
// Cleanup on unmount
onUnmounted(() => {
__TOKEN_34__ (intervalId) clearInterval(intervalId);
});
return {
seconds,
minutes,
hours,
isRunning,
start,
pause,
reset
};
}
// Usage example
// const { seconds, minutes, isRunning, start, pause, reset } = useCountdown(120);
// start(); // Start countdown
// pause(); // Pause countdown
// reset(180); // Reset to 3 minutes