Skip to content

Countdown 倒计时 ​

精准倒计时组件,核心调度基于系统绝对时间戳差值计算。当浏览器标签页从后台休眠唤醒时自适应校准,杜绝累积定时器漂移,并内置读屏高频降噪与到期通知。为保证 SSR 水合首帧一致,服务端和客户端初次渲染显示占位文本;读取浏览器时钟并启动计时从挂载后开始。

预览 ​

Preview
发版倒计时
-
精准计时
-

安装 ​

pnpm dlx brutx-vue@latest add countdown

用法 ​

vue
<script setup>
import { onMounted, ref } from 'vue'
import { Countdown } from 'brutx-ui-vue'

const ONE_DAY_MS = 24 * 60 * 60 * 1000
const targetTime = ref<number | null>(null)

onMounted(() => {
    targetTime.value = Date.now() + ONE_DAY_MS
})
</script>

<template>
    <!-- 基础倒计时 -->
    <Countdown title="剩余时间" :value="targetTime" />

    <!-- 自定义时间格式与卡片变体 -->
    <Countdown
        title="活动截止"
        :value="targetTime"
        format="DD [天] HH [时] mm [分] ss [秒]"
        variant="card"
    />
</template>

SSR 首帧与自定义内容 ​

SSR 和水合期间,组件会先显示 placeholder(默认 -),挂载后才按 value 目标时间计算剩余时间。默认插槽的 formatted 在准备完成前也是占位文本;这时 remaining 为 0、isFinished 为 false。isReady 会在挂载并完成首次计算后变为 true,此时 remaining 和 isFinished 才对应当前目标。

vue
<Countdown :value="targetTime">
    <template #default="{ formatted, isReady }">
        {{ isReady ? formatted : '正在准备倒计时' }}
    </template>
</Countdown>

毫秒级刷新与格式化转义 ​

在 format 格式化字符串中包含 SSS 时会自动以高频(~30fps)刷新毫秒。普通文本字符若包含保留标识(如 D、H、m、s)时,可用方括号 [...] 包裹转义:

vue
<script setup>
import { onMounted, ref } from 'vue'

const ONE_MINUTE_MS = 60 * 1000
const targetTime = ref<number | null>(null)

onMounted(() => {
    targetTime.value = Date.now() + ONE_MINUTE_MS
})
</script>

<template>
    <Countdown
        title="秒杀倒计时"
        :value="targetTime"
        format="mm:ss.SSS"
        variant="card"
    />
</template>

到期回调 ​

通过 @finish 监听倒计时归零事件,通过 @change 监听剩余毫秒数变化:

vue
<script setup>
import { onMounted, ref } from 'vue'
import { Countdown } from 'brutx-ui-vue'

const FIVE_SECONDS_MS = 5 * 1000
const targetTime = ref<number | null>(null)

onMounted(() => {
    targetTime.value = Date.now() + FIVE_SECONDS_MS
})

function onFinish() {
    console.log('倒计时结束!')
}

function onChange(remainingMs: number) {
    console.log('剩余毫秒:', remainingMs)
}
</script>

<template>
    <Countdown
        :value="targetTime"
        @finish="onFinish"
        @change="onChange"
    />
</template>

变体 ​

变体说明
default默认变体,轻量内联排版,无额外背景与边框
card粗野主义卡片,3px 黑色硬边框、硬阴影、内边距与圆角
bordered粗黑硬边框卡片,无投影
subtle浅色高亮背景卡片,带粗黑边框与硬阴影
vue
<template>
    <Countdown title="Default" :value="targetTime" variant="default" />
    <Countdown title="Card" :value="targetTime" variant="card" />
    <Countdown title="Bordered" :value="targetTime" variant="bordered" />
    <Countdown title="Subtle" :value="targetTime" variant="subtle" />
</template>

尺寸 ​

尺寸标题字号数值字号
smtext-xstext-2xl
defaulttext-smtext-3xl sm:text-4xl
lgtext-basetext-4xl sm:text-5xl
vue
<template>
    <Countdown title="小型" :value="targetTime" size="sm" variant="card" />
    <Countdown title="标准" :value="targetTime" size="default" variant="card" />
    <Countdown title="大型" :value="targetTime" size="lg" variant="card" />
</template>

导出类型 ​

组件导出了变体函数与格式化解析工具函数:

ts
import type {
    CountdownProps,
    CountdownValue,
    CountdownEmits,
    CountdownVariantProps,
} from 'brutx-ui-vue'
import {
    countdownVariants,
    parseCountdownTarget,
    formatCountdown,
} from 'brutx-ui-vue'

API 参考 ​

Countdown — 属性
名称类型默认值说明
value
可空
CountdownValue
undefined
倒计时的目标时间点,支持毫秒时间戳、Date、纯数字时间戳字符串及可解析的日期字符串;空值或无效日期显示占位文本。
详情

声明类型

CountdownValue

字面量

  • null

关联类型

CountdownValue
类型定义 — CountdownValue
export type CountdownValue = number | string | Date | null | undefined

默认值详情

解析值
undefined

来源

types.ts:10

packages/ui/src/components/countdown/types.ts

format
string | undefined
"HH:mm:ss"
剩余时间格式,支持 DD、D、HH、H、mm、m、ss、s、SSS、SS、S 和方括号转义文本。包含 S 时使用毫秒级刷新。
详情

声明类型

string | undefined

默认值详情

解析值
"HH:mm:ss"

来源

types.ts:11

packages/ui/src/components/countdown/types.ts

title
string | undefined
undefined
显示在倒计时数值上方的标题文本,title 插槽可替换其内容。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

types.ts:12

packages/ui/src/components/countdown/types.ts

prefix
string | undefined
undefined
显示在倒计时数值前的文本,prefix 插槽可替换其内容。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

types.ts:13

packages/ui/src/components/countdown/types.ts

suffix
string | undefined
undefined
显示在倒计时数值后的文本,suffix 插槽可替换其内容。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

types.ts:14

packages/ui/src/components/countdown/types.ts

placeholder
string | undefined
undefined

运行时回退:未提供时使用短横线“-”。

挂载前或目标时间为空、无效时显示的占位文本。
详情

声明类型

string | undefined

默认值详情

解析值
undefined
运行时回退
未提供时使用短横线“-”。

组件在说明的运行条件下采用此回退值。

来源

types.ts:15

packages/ui/src/components/countdown/types.ts

variant
"bordered" | "card" | "default" | "subtle" | undefined
"default"
倒计时外层容器的背景和边框变体。
详情

声明类型

NonNullable<"default" | "card" | "bordered" | "subtle" | null | undefined> | undefined

字面量

  • "bordered"
  • "card"
  • "default"
  • "subtle"

默认值详情

解析值
"default"

来源

types.ts:16

packages/ui/src/components/countdown/types.ts

size
"default" | "lg" | "sm" | undefined
"default"
传给内部 Statistic 的尺寸,控制数值与配套文字的大小。
详情

声明类型

NonNullable<"default" | "lg" | "sm" | null | undefined> | undefined

字面量

  • "default"
  • "lg"
  • "sm"

默认值详情

解析值
"default"

来源

types.ts:17

packages/ui/src/components/countdown/types.ts

class
string | undefined
undefined
合并到倒计时外层容器的自定义 CSS 类。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

types.ts:18

packages/ui/src/components/countdown/types.ts

Countdown — 事件
名称签名或类型说明
@change
[remaining: number]
计时刷新或目标时间重新计算时发出剩余毫秒数,最小为零。
详情

声明类型

[remaining: number]

来源

Countdown.vue

packages/ui/src/components/countdown/Countdown.vue

@finish
[]
有效倒计时进入完成状态时发出;挂载时目标已到期也会发出。新的未来目标会重新开始计时并允许再次完成。
详情

声明类型

[]

来源

Countdown.vue

packages/ui/src/components/countdown/Countdown.vue

Countdown — 插槽
名称签名或类型说明
#title
{ title?: string | undefined; }
自定义标题区域,接收 title 属性值;默认显示该文本。
详情

声明类型

{ title?: string | undefined; }

来源

Countdown.vue:26

packages/ui/src/components/countdown/Countdown.vue

#prefix
{ prefix?: string | undefined; }
自定义数值前缀区域,接收 prefix 属性值。
详情

声明类型

{ prefix?: string | undefined; }

来源

Countdown.vue:27

packages/ui/src/components/countdown/Countdown.vue

#suffix
{ suffix?: string | undefined; }
自定义数值后缀区域,接收 suffix 属性值。
详情

声明类型

{ suffix?: string | undefined; }

来源

Countdown.vue:28

packages/ui/src/components/countdown/Countdown.vue

#default
{ remaining: number; formatted: string; isFinished: boolean; isReady: boolean; }
自定义数值区域,接收剩余毫秒数、格式化字符串、是否完成及是否已挂载的 isReady 状态。
详情

声明类型

{ remaining: number; formatted: string; isFinished: boolean; isReady: boolean; }

来源

Countdown.vue:29

packages/ui/src/components/countdown/Countdown.vue

可访问性 ​

  • 键盘操作:时序展示类组件,不捕获键盘输入;嵌套在交互区块中时,焦点遵循 DOM 正常流转。
  • ARIA 属性:高频走字期间保持 aria-live 静默,防止屏幕阅读器频繁读秒骚扰用户;倒计时到达零值时通过 aria-live="polite" 触发一次性完成语音通知。
  • 焦点管理:无内部模态或焦点锁定,不干预辅助技术正常光标导航。
  • 数字排版:使用等宽数字(font-mono)减少更新时的宽度变化。剩余时间依据当前时钟计算,计时调度在挂载后启动;自定义默认插槽可用 isReady 区分占位首帧与已计算状态。

蛮力铸就。