@brmtech/countdown
v0.1.0
Published
A TypeScript countdown and duration formatting utility.
Readme
@brmtech/countdown
一个轻量的 TypeScript 倒计时工具,提供秒数格式化、通用倒计时控制器,以及适合 Vue/React 等 UI 场景使用的数字拆分结果。
安装
npm install @brmtech/countdown快速开始
import { createCountdown, formatDuration } from '@brmtech/countdown';
console.log(formatDuration(90));
// '00:00:01:30'
const countdown = createCountdown(90, {
units: ['minute', 'second'],
onTick(snapshot) {
console.log(snapshot.formatted);
},
onFinish() {
console.log('done');
},
});
countdown.start();导出的 API
import {
formatDuration,
createCountdown,
useFormatTime,
} from '@brmtech/countdown';默认导出为 useFormatTime:
import useFormatTime from '@brmtech/countdown';formatDuration(seconds, options?)
把总秒数格式化为字符串,或返回适合数字格子 UI 渲染的对象数组。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| seconds | number \| string | 是 | - | 总秒数。负数、NaN、Infinity 会按 0 处理;小数会向上取整。 |
| options.units | CountdownUnit[] | 否 | ['day', 'hour', 'minute', 'second'] | 输出单位及顺序。可选值:day、days、hour、hours、minute、minutes、second、seconds。省略更大单位时,剩余时间会累加到当前最大展示单位。 |
| options.separator | string | 否 | ':' | returnType 为 string 时,各单位之间的连接符。 |
| options.labels | Partial<Record<CountdownUnit, string>> | 否 | {} | 单位标签,会追加在每个展示值后。 |
| options.template | string | 否 | - | 自定义每个单位的字符串模板,支持 {value}、{raw}、{unit}、{label}。 |
| options.padZero | boolean | 否 | true | 是否把每个单位补齐到两位。 |
| options.trimZero | boolean | 否 | false | 是否移除字符串输出中的前置零单位。 |
| options.compact | boolean | 否 | false | trimZero 的别名。 |
| options.returnType | 'string' \| 'object' | 否 | 'string' | 返回字符串或对象数组。 |
返回值
当 returnType 为 string 时返回:
string当 returnType 为 object 时返回:
Array<{
key: CountdownUnit;
value: string;
digits: string[];
}>示例
formatDuration(90061);
// '01:01:01:01'
formatDuration('90', {
units: ['minute', 'second'],
});
// '01:30'
formatDuration(90061, {
units: ['hours', 'minutes', 'seconds'],
separator: '-',
});
// '25-01-01'
formatDuration(61, {
units: ['minutes', 'seconds'],
returnType: 'object',
});
// [
// { key: 'minutes', value: '01', digits: ['0', '1'] },
// { key: 'seconds', value: '01', digits: ['0', '1'] }
// ]
formatDuration(61, {
units: ['minute', 'second'],
padZero: false,
});
// '1:1'
formatDuration(90, {
units: ['day', 'hour', 'minute', 'second'],
labels: { minute: 'm', second: 's' },
separator: ' ',
compact: true,
});
// '01m 30s'
formatDuration(1.25, {
units: ['second', 'millisecond'],
labels: { second: 's', millisecond: 'ms' },
separator: ' ',
template: '{raw}{label}',
});
// '1s 250ms'createCountdown(secondsOrOptions?, options?)
创建一个可开始、暂停、恢复、停止、重置和手动结束的倒计时控制器。它用结束时间计算真实剩余秒数,因此页面卡顿或定时器延迟时也会自动校正。
调用方式
createCountdown(90);
createCountdown('90', { units: ['minute', 'second'] });
createCountdown({ seconds: 90, autoStart: true });
createCountdown({ endTime: Date.now() + 10 * 60 * 1000 });配置参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| seconds | number \| string | 否 | 0 | 总秒数。 |
| duration | number \| string | 否 | - | 总秒数,等同 seconds。 |
| durationMs | number \| string | 否 | - | 总毫秒数,会转换为秒。 |
| endTime | number \| string \| Date | 否 | - | 结束时间,支持秒级时间戳、毫秒级时间戳、日期字符串、Date。 |
| targetTime | number \| string \| Date | 否 | - | 结束时间,等同 endTime。 |
| interval | number | 否 | 1000 | 刷新间隔,单位毫秒。只影响回调频率,不影响真实剩余时间计算。 |
| autoStart | boolean | 否 | false | 创建后是否自动开始。 |
| immediate | boolean | 否 | true | start、reset、setRemaining、finish 时是否立即触发一次 onTick。 |
| units | CountdownUnit[] | 否 | ['day', 'hour', 'minute', 'second'] | 默认格式化单位。 |
| separator | string | 否 | ':' | 默认格式化连接符。 |
| padZero | boolean | 否 | true | 默认是否补零。 |
| returnType | 'string' \| 'object' | 否 | 'string' | snapshot.formatted 的默认返回类型。 |
| formatter | (remaining, formatOptions) => string \| DurationPart[] | 否 | formatDuration | 自定义格式化函数。 |
| formatOptions | FormatDurationOptions | 否 | 当前配置对象 | 传给 formatter 的配置。 |
| signal | AbortSignal | 否 | - | 外部中止信号,触发后会自动 stop()。 |
| onTick | (snapshot) => void | 否 | - | 每次触发快照时调用。 |
| onChange | (snapshot) => void | 否 | - | 公开控制方法改变状态或剩余时间后调用。 |
| onStatusChange | (change) => void | 否 | - | idle、running、paused、stopped、finished 状态变化时调用。 |
| onFinish | (snapshot) => void | 否 | - | 当前这一轮倒计时归零时调用一次。 |
当第一个参数是对象时,会和第二个 options 合并,第二个 options 优先级更高。
返回控制器
| 属性/方法 | 类型 | 说明 |
| --- | --- | --- |
| start(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 开始倒计时。传入参数时会先重设总时长。 |
| pause() | () => CountdownSnapshot | 暂停并保留当前剩余秒数。 |
| resume(seconds?) | 同 start | 继续倒计时。它是 start 的别名。 |
| stop() | () => CountdownSnapshot | 停止定时器并保留当前状态。 |
| finish() | () => CountdownSnapshot | 立即归零,并触发 onFinish。 |
| reset(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 重置倒计时;如果重置前正在运行,会继续运行。 |
| restart(seconds?) | (seconds?: number \| string \| CountdownOptions) => CountdownSnapshot | 重置并立即开始。 |
| add(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 给当前剩余时间增加秒数或配置中的时长。 |
| subtract(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 从当前剩余时间扣减秒数或配置中的时长。 |
| setRemaining(seconds) | (seconds: number \| string \| CountdownOptions) => CountdownSnapshot | 手动设置剩余秒数。 |
| getSnapshot() | () => CountdownSnapshot | 获取当前快照。 |
| remaining | number | 当前剩余秒数。 |
| remainingMs | number | 当前剩余毫秒数。 |
| parts | DurationPart[] | 当前拆分后的单位数组。 |
| formatted | string \| DurationPart[] | 当前格式化结果。 |
| progress | number | 当前进度,范围 0 到 1。 |
| percent | number | 当前进度百分比,范围 0 到 100。 |
| status | 'idle' \| 'running' \| 'paused' \| 'stopped' \| 'finished' | 当前状态。 |
| isRunning | boolean | 是否正在运行。 |
| isFinished | boolean | 是否已归零。 |
CountdownSnapshot
interface CountdownSnapshot {
total: number;
totalMs: number;
remaining: number;
remainingMs: number;
elapsed: number;
elapsedMs: number;
formatted: string | DurationPart[];
parts: DurationPart[];
progress: number;
percent: number;
status: 'idle' | 'running' | 'paused' | 'stopped' | 'finished';
isRunning: boolean;
isFinished: boolean;
}| 字段 | 说明 |
| --- | --- |
| total | 本轮倒计时初始秒数。 |
| totalMs | 本轮倒计时初始毫秒数。 |
| remaining | 当前剩余秒数。 |
| remainingMs | 当前剩余毫秒数。 |
| elapsed | 已经过秒数。 |
| elapsedMs | 已经过毫秒数。 |
| formatted | 格式化后的展示值。 |
| parts | 拆分后的单位数组,适合数字格子 UI。 |
| progress | 当前进度,范围 0 到 1。 |
| percent | 当前进度百分比,范围 0 到 100。 |
| status | 当前状态。 |
| isRunning | 当前是否正在运行。 |
| isFinished | 当前是否已归零。 |
示例:基础倒计时
const countdown = createCountdown(90, {
units: ['minute', 'second'],
onTick({ remaining, formatted }) {
console.log(remaining, formatted);
},
onFinish() {
console.log('done');
},
});
countdown.start();示例:接口返回字符串秒数
const countdown = createCountdown('90', {
units: ['minute', 'second'],
onTick({ formatted }) {
console.log(formatted);
},
});
countdown.start();示例:按结束时间倒计时
const countdown = createCountdown({
endTime: Date.now() + 10 * 60 * 1000,
units: ['minute', 'second'],
autoStart: true,
onTick({ formatted }) {
console.log(formatted);
},
});示例:数字格子 UI
const countdown = createCountdown(90061, {
units: ['hours', 'minutes', 'seconds'],
onTick({ parts }) {
for (const part of parts) {
console.log(part.key, part.digits);
}
},
});
countdown.start();示例:formatted 直接返回对象数组
const countdown = createCountdown(90061, {
returnType: 'object',
onTick({ formatted }) {
console.log(formatted);
},
});
countdown.start();示例:手动控制
const countdown = createCountdown(120);
countdown.start();
countdown.pause();
countdown.resume();
countdown.setRemaining(30);
countdown.reset(60);
countdown.finish();
countdown.stop();示例:Vue 中使用
import { onMounted, onUnmounted, ref } from 'vue';
import { createCountdown } from '@brmtech/countdown';
const timeText = ref('00:00');
const countdown = createCountdown(90, {
units: ['minute', 'second'],
onTick({ formatted }) {
timeText.value = String(formatted);
},
onFinish() {
console.log('finish');
},
});
onMounted(() => countdown.start());
onUnmounted(() => countdown.stop());useFormatTime()
返回当前包提供的两个核心工具,适合在业务代码里统一注入或解构使用。
返回值
{
formatDuration,
createCountdown,
}示例
import { useFormatTime } from '@brmtech/countdown';
const { formatDuration, createCountdown } = useFormatTime();
console.log(formatDuration(61, { units: ['minute', 'second'] }));
const countdown = createCountdown(10, {
onFinish() {
console.log('done');
},
});类型导出
import type {
CountdownController,
CountdownFormatter,
CountdownOptions,
CountdownSecondsInput,
CountdownSnapshot,
CountdownStartInput,
CountdownTimeInput,
CountdownUnit,
DurationPart,
FormatDurationOptions,
FormattedDuration,
FormatTimeHelpers,
} from '@brmtech/countdown';