chore: move useCountdown to @vant/use
This commit is contained in:
@@ -5,8 +5,8 @@ import { createNamespace } from '../utils';
|
||||
import { parseFormat } from './utils';
|
||||
|
||||
// Composition
|
||||
import { useCountDown } from '@vant/use';
|
||||
import { useExpose } from '../composition/use-expose';
|
||||
import { useCountDown } from './use-count-down';
|
||||
|
||||
const [createComponent, bem] = createNamespace('count-down');
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
onActivated,
|
||||
onDeactivated,
|
||||
onBeforeUnmount,
|
||||
} from 'vue';
|
||||
import { raf, cancelRaf } from '../utils';
|
||||
|
||||
export type CurrentTime = {
|
||||
days: number;
|
||||
hours: number;
|
||||
total: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
milliseconds: number;
|
||||
};
|
||||
|
||||
export type UseCountDownOptions = {
|
||||
time: number;
|
||||
millisecond?: boolean;
|
||||
onChange?: (current: CurrentTime) => void;
|
||||
onFinish?: () => void;
|
||||
};
|
||||
|
||||
const SECOND = 1000;
|
||||
const MINUTE = 60 * SECOND;
|
||||
const HOUR = 60 * MINUTE;
|
||||
const DAY = 24 * HOUR;
|
||||
|
||||
export function parseTime(time: number): CurrentTime {
|
||||
const days = Math.floor(time / DAY);
|
||||
const hours = Math.floor((time % DAY) / HOUR);
|
||||
const minutes = Math.floor((time % HOUR) / MINUTE);
|
||||
const seconds = Math.floor((time % MINUTE) / SECOND);
|
||||
const milliseconds = Math.floor(time % SECOND);
|
||||
|
||||
return {
|
||||
total: time,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds,
|
||||
};
|
||||
}
|
||||
|
||||
function isSameSecond(time1: number, time2: number): boolean {
|
||||
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
|
||||
}
|
||||
|
||||
export function useCountDown(options: UseCountDownOptions) {
|
||||
let rafId: number;
|
||||
let endTime: number;
|
||||
let counting: boolean;
|
||||
let deactivated: boolean;
|
||||
|
||||
const remain = ref(options.time);
|
||||
const current = computed(() => parseTime(remain.value));
|
||||
|
||||
const pause = () => {
|
||||
counting = false;
|
||||
cancelRaf(rafId);
|
||||
};
|
||||
|
||||
const getCurrentRemain = () => Math.max(endTime - Date.now(), 0);
|
||||
|
||||
const setRemain = (value: number) => {
|
||||
remain.value = value;
|
||||
options.onChange?.(current.value);
|
||||
|
||||
if (value === 0) {
|
||||
pause();
|
||||
options.onFinish?.();
|
||||
}
|
||||
};
|
||||
|
||||
const microTick = () => {
|
||||
rafId = raf(() => {
|
||||
// in case of call reset immediately after finish
|
||||
if (counting) {
|
||||
setRemain(getCurrentRemain());
|
||||
|
||||
if (remain.value > 0) {
|
||||
microTick();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const macroTick = () => {
|
||||
rafId = raf(() => {
|
||||
// in case of call reset immediately after finish
|
||||
if (counting) {
|
||||
const remainRemain = getCurrentRemain();
|
||||
|
||||
if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
|
||||
setRemain(remainRemain);
|
||||
}
|
||||
|
||||
if (remain.value > 0) {
|
||||
macroTick();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const tick = () => {
|
||||
if (options.millisecond) {
|
||||
microTick();
|
||||
} else {
|
||||
macroTick();
|
||||
}
|
||||
};
|
||||
|
||||
const start = () => {
|
||||
if (!counting) {
|
||||
endTime = Date.now() + remain.value;
|
||||
counting = true;
|
||||
tick();
|
||||
}
|
||||
};
|
||||
|
||||
const reset = (totalTime: number) => {
|
||||
pause();
|
||||
remain.value = totalTime;
|
||||
};
|
||||
|
||||
onBeforeUnmount(pause);
|
||||
|
||||
onActivated(() => {
|
||||
if (deactivated) {
|
||||
counting = true;
|
||||
deactivated = false;
|
||||
tick();
|
||||
}
|
||||
});
|
||||
|
||||
onDeactivated(() => {
|
||||
if (counting) {
|
||||
pause();
|
||||
deactivated = true;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
start,
|
||||
pause,
|
||||
reset,
|
||||
current,
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { padZero } from '../utils';
|
||||
import { CurrentTime } from './use-count-down';
|
||||
import { CurrentTime } from '@vant/use';
|
||||
|
||||
export function parseFormat(format: string, currentTime: CurrentTime): string {
|
||||
const { days } = currentTime;
|
||||
|
||||
Reference in New Issue
Block a user