CountDown 倒计时
# m-count-down 倒计时
用于展示剩余时间的倒计时组件,支持自定义格式、毫秒级精度、手动控制及插槽自定义渲染,适用于活动倒计时、验证码等待、订单超时等场景。
# 基本用法
<template>
<m-count-down :time="3661000" />
</template>
<script setup lang="ts">
import mCountDown from '@/packages/m-count-down/m-count-down.vue'
</script>
# 属性(Props)
| 参数名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| time | 倒计时时长,单位为毫秒(ms),必传 | number | - |
| format | 时间格式化模板,支持的占位符见下方说明 | string | 'HH:mm:ss' |
| millisecond | 是否开启毫秒级刷新(约每 30ms 更新一次) | boolean | false |
| auto-start | 是否在挂载 / time 变化时自动开始倒计时 | boolean | true |
| custom-class | 自定义类名 | string | '' |
| custom-style | 自定义样式 | string | '' |
# format 占位符说明
| 占位符 | 说明 | 示例 |
|---|---|---|
| DD | 天数(两位补零) | 02 |
| HH | 小时(两位补零) | 08 |
| mm | 分钟(两位补零) | 30 |
| ss | 秒数(两位补零) | 45 |
| SSS | 毫秒(三位补零) | 120 |
| S | 毫秒(不补零) | 120 |
非占位符字符会原样输出,例如
"DD天 HH时 mm分 ss秒"→"02天 08时 30分 45秒"。
# 事件(Events)
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 倒计时每次更新时触发 | current: CurrentTime(包含 days, hours, minutes, seconds, milliseconds 等字段) |
| finish | 倒计时归零结束时触发 | - |
# 插槽(Slots)
| 插槽名 | 说明 | 插槽参数 |
|---|---|---|
| default | 自定义倒计时渲染内容,传入后默认文本不再显示 | { current: CurrentTime } |
# 方法(Methods)
通过组件 ref 调用:
| 方法名 | 说明 |
|---|---|
| start() | 开始倒计时 |
| pause() | 暂停倒计时 |
| reset() | 重置倒计时到初始 time 值;若 auto-start 为 true,重置后自动开始 |
<m-count-down ref="countDownRef" :time="60000" :auto-start="false" />
<script setup lang="ts">
import { ref } from 'vue'
import type { CountDownInstance } from '@/packages/m-count-down/types'
const countDownRef = ref<CountDownInstance>()
function handleStart() { countDownRef.value?.start() }
function handlePause() { countDownRef.value?.pause() }
function handleReset() { countDownRef.value?.reset() }
</script>
# 完整示例
<template>
<!-- 基础用法 -->
<m-count-down :time="3661000" />
<!-- 自定义格式 -->
<m-count-down :time="86400000 * 2 + 3661000" format="DD天 HH时 mm分 ss秒" />
<m-count-down :time="61000" format="mm分ss秒" />
<!-- 毫秒级显示 -->
<m-count-down :time="60000" millisecond format="HH:mm:ss.SSS" />
<!-- 手动控制 -->
<m-count-down ref="countDownRef" :time="60000" format="mm:ss" />
<button @click="countDownRef?.start()">开始</button>
<button @click="countDownRef?.pause()">暂停</button>
<button @click="countDownRef?.reset()">重置</button>
<!-- 不自动开始 -->
<m-count-down ref="manualRef" :time="30000" :auto-start="false" format="ss秒" />
<button @click="manualRef?.start()">点击开始</button>
<!-- 插槽自定义样式 -->
<m-count-down :time="3661000">
<template #default="{ current }">
<view class="custom-count">
<view class="count-item">
<text class="num">{{ padZero(current.hours) }}</text>
<text class="label">时</text>
</view>
<text class="sep">:</text>
<view class="count-item">
<text class="num">{{ padZero(current.minutes) }}</text>
<text class="label">分</text>
</view>
<text class="sep">:</text>
<view class="count-item">
<text class="num">{{ padZero(current.seconds) }}</text>
<text class="label">秒</text>
</view>
</view>
</template>
</m-count-down>
<!-- 监听事件 -->
<m-count-down :time="10000" @change="onChange" @finish="onFinish" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import mCountDown from '@/packages/m-count-down/m-count-down.vue'
import type { CountDownInstance } from '@/packages/m-count-down/types'
const countDownRef = ref<CountDownInstance>()
const manualRef = ref<CountDownInstance>()
function padZero(num: number) {
return num.toString().padStart(2, '0')
}
function onChange(current: any) {
console.log('倒计时更新:', current)
}
function onFinish() {
console.log('倒计时结束')
}
</script>
<style scoped lang="scss">
.custom-count {
display: flex;
align-items: center;
}
.count-item {
display: flex;
flex-direction: column;
align-items: center;
background-color: #1e293b;
padding: 8px 12px;
border-radius: 6px;
}
.num { font-size: 18px; font-weight: 600; color: #fff; }
.label { font-size: 10px; color: #94a3b8; margin-top: 2px; }
.sep { font-size: 16px; font-weight: bold; color: #1e293b; margin: 0 6px; }
</style>
# 注意事项
- time 单位:
time属性单位为毫秒,传入秒级数值会导致倒计时远短于预期。例如 1 小时应传3600000而非3600。 - millisecond 性能影响:开启毫秒级后刷新频率约为 30ms/次,在列表或大量实例场景下可能造成性能问题,建议仅在单个关键倒计时中使用。
- auto-start 与 reset 联动:调用
reset()时,若auto-start为true,重置后会自动重新开始;若为false,需手动调用start()。 - time 变化行为:运行时修改
time属性会触发内部resetTime,即重置倒计时并根据auto-start决定是否自动开始,不会从当前剩余时间继续。 - format 大小写敏感:占位符严格区分大小写,
hh、MM、SS等不会被识别,将作为普通文本原样输出。 - 插槽与默认文本互斥:传入默认插槽后,组件仅渲染插槽内容,
format和timeText不再生效;但current对象仍正常计算并传递给插槽。 - 平台差异:组件 options 中使用了
virtualHost: true,该选项在头条小程序(MP-TOUTIAO)下被条件编译排除;其他平台虚拟宿主节点生效。 - 依赖外部模块:格式化逻辑依赖
./utils中的parseFormat函数,计时逻辑依赖../composables/useCountDown,确保这两个模块路径正确且可用。
上次更新: 2026/09/11, 09:41:41