Appearance
Countdown 倒计时
基于 Vue 3 的高性能倒计时组件,使用全局共享定时器实现,所有组件实例共用一个定时器,节省性能开销。
基本用法
vue
<template>
<div>
<!-- 基本倒计时(使用秒数) -->
<g-countdown :target="60"></g-countdown>
<!-- 使用目标时间戳 -->
<g-countdown :target="targetTimestamp"></g-countdown>
<!-- 自定义格式 -->
<g-countdown :target="120" format="{minutes}:{seconds}"></g-countdown>
<!-- 手动控制 -->
<div>
<g-countdown ref="countdownRef" :target="300" :auto-start="false"></g-countdown>
<el-button @click="handleStart">开始</el-button>
<el-button @click="handlePause">暂停</el-button>
<el-button @click="handleReset">重置</el-button>
</div>
<!-- 自定义内容 -->
<g-countdown :target="86400">
<template v-slot="{ days, hours, minutes, seconds }">
<span class="time-item">{{ days }}</span
>天 <span class="time-item">{{ hours }}</span
>时 <span class="time-item">{{ minutes }}</span
>分 <span class="time-item">{{ seconds }}</span
>秒
</template>
</g-countdown>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 目标时间戳(明天这个时候)
const targetTimestamp = ref(Date.now() + 24 * 60 * 60 * 1000)
// 手动控制的倒计时
const countdownRef = ref(null)
const handleStart = () => countdownRef.value?.start()
const handlePause = () => countdownRef.value?.pause()
const handleReset = () => countdownRef.value?.reset()
</script>
<style scoped>
.time-item {
background-color: #409eff;
color: white;
padding: 2px 6px;
border-radius: 4px;
font-weight: bold;
}
</style>属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| target | 目标时间戳(毫秒)或倒计时秒数 | Number/String | 必填 |
| autoStart | 是否自动开始倒计时 | Boolean | true |
| stopOnZero | 是否在倒计时结束后停止 | Boolean | true |
| customClass | 自定义类名 | String/Array/Object | '' |
| format | 格式化模板,支持 {days}, {hours}, {minutes}, {seconds} 占位符 | String | '{days}天{hours}小时{minutes}分{seconds}秒' |
| leadingZero | 是否显示前导零 | Boolean | true |
事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| finish | 倒计时结束时触发 | - |
| tick | 每秒更新时触发 | {days, hours, minutes, seconds, total} |
| update:target | 更新目标时间时触发 | target |
插槽
| 插槽名 | 说明 | 作用域参数 |
|---|---|---|
| default | 自定义倒计时显示内容 | { days, hours, minutes, seconds } |
方法
| 方法名 | 说明 | 参数 |
|---|---|---|
| start | 开始倒计时 | - |
| pause | 暂停倒计时 | - |
| reset | 重置倒计时 | - |
组件实例属性
| 属性名 | 说明 | 类型 |
|---|---|---|
| remainingTime | 当前剩余时间(秒) | Number |
全局定时器管理器
组件内部使用了全局定时器管理器 timerManager,确保所有 Countdown 组件实例共享同一个定时器,有效减少浏览器性能消耗。主要功能包括:
- 自动管理定时器的创建和销毁
- 当所有倒计时组件都被销毁时,自动清除定时器
- 通过发布-订阅模式通知所有组件更新
- 错误捕获,防止单个组件错误影响整个定时器
高级用法
动态更新目标时间
vue
<template>
<div>
<g-countdown v-model:target="targetTime"></g-countdown>
<el-button @click="updateTarget">更新目标时间</el-button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const targetTime = ref(60)
const updateTarget = () => {
targetTime.value = 120 // 更新为120秒
}
</script>监听倒计时状态
vue
<template>
<g-countdown :target="targetTime" @finish="handleFinish" @tick="handleTick"></g-countdown>
</template>
<script setup>
import { ref } from 'vue'
const targetTime = ref(10)
const handleFinish = () => {
console.log('倒计时结束!')
// 可以在这里执行一些操作,如显示提示、触发新流程等
}
const handleTick = (timeInfo) => {
console.log('当前倒计时状态:', timeInfo)
// timeInfo = { days, hours, minutes, seconds, total }
}
</script>自定义样式
vue
<template>
<g-countdown :target="86400" class="custom-countdown"></g-countdown>
</template>
<style scoped>
.custom-countdown {
font-size: 20px;
font-weight: bold;
color: #409eff;
/* 可以通过CSS选择器定位不同部分 */
&:deep(.g-countdown) {
letter-spacing: 2px;
}
}
</style>注意事项
- 性能优化:组件使用全局定时器共享机制,适合在页面中使用多个倒计时组件的场景
- 时间精度:倒计时基于JavaScript定时器实现,精度可能受到浏览器性能影响
- 目标时间判断:组件会自动判断传入的target值是时间戳还是秒数(大于2001年时间戳阈值的被视为时间戳)
- 组件销毁:组件会在卸载时自动清理定时器订阅,无需手动处理
样式定制
组件默认样式简洁,可以通过 customClass 属性或直接在父组件中使用深度选择器进行样式定制。