vue实现倒计时
Vue 实现倒计时的基本方法
使用 setInterval 和响应式数据
在 Vue 组件中定义一个响应式变量(如 countdown),通过 setInterval 每秒更新数值。组件销毁时清除定时器避免内存泄漏。
<template>
<div>{{ formattedTime }}</div>
</template>
<script>
export default {
data() {
return {
countdown: 60, // 初始秒数
timer: null
}
},
computed: {
formattedTime() {
const minutes = Math.floor(this.countdown / 60);
const seconds = this.countdown % 60;
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}
},
mounted() {
this.timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--;
} else {
clearInterval(this.timer);
}
}, 1000);
},
beforeDestroy() {
clearInterval(this.timer);
}
}
</script>
使用 Composition API(Vue 3)
通过 ref 和 onMounted/onUnmounted 实现更简洁的逻辑:
<template>
<div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue';
const countdown = ref(60);
let timer = null;
const minutes = computed(() => Math.floor(countdown.value / 60));
const seconds = computed(() => countdown.value % 60);
onMounted(() => {
timer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
clearInterval(timer);
}
}, 1000);
});
onUnmounted(() => clearInterval(timer));
</script>
封装可复用的倒计时 Hook(Vue 3)
将逻辑抽离为自定义 Hook,便于多处复用:
// useCountdown.js
import { ref, computed, onUnmounted } from 'vue';
export function useCountdown(initialTime) {
const countdown = ref(initialTime);
let timer = null;
const start = () => {
timer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
clearInterval(timer);
}
}, 1000);
};
const minutes = computed(() => Math.floor(countdown.value / 60));
const seconds = computed(() => countdown.value % 60);
onUnmounted(() => clearInterval(timer));
return { countdown, minutes, seconds, start };
}
组件中使用:
<template>
<div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
</template>
<script setup>
import { useCountdown } from './useCountdown';
const { minutes, seconds } = useCountdown(60);
</script>
支持暂停和重置功能
扩展基础倒计时,增加控制方法:
<template>
<div>
<div>{{ minutes }}:{{ seconds < 10 ? '0' : '' }}{{ seconds }}</div>
<button @click="pause">暂停</button>
<button @click="reset">重置</button>
</div>
</template>
<script>
export default {
data() {
return {
countdown: 60,
timer: null,
isPaused: false
}
},
methods: {
pause() {
this.isPaused = !this.isPaused;
if (this.isPaused) {
clearInterval(this.timer);
} else {
this.startTimer();
}
},
reset() {
clearInterval(this.timer);
this.countdown = 60;
this.startTimer();
},
startTimer() {
this.timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--;
} else {
clearInterval(this.timer);
}
}, 1000);
}
},
mounted() {
this.startTimer();
}
}
</script>
注意事项
- 定时器清理:务必在组件销毁时清除定时器,防止内存泄漏。
- 性能优化:频繁操作 DOM 时考虑使用
requestAnimationFrame。 - 格式化显示:通过计算属性处理时间格式,保持模板简洁。
- 跨组件通信:如需全局倒计时,可通过 Vuex/Pinia 管理状态。







