vue 实现多个倒计
实现多个独立倒计时
在Vue中实现多个独立倒计时可以通过v-for循环渲染多个计时器组件,每个组件管理自己的倒计时状态。以下是实现方式:
<template>
<div>
<div v-for="(timer, index) in timers" :key="index">
<p>倒计时 {{ index + 1 }}: {{ formatTime(timer.remaining) }}</p>
<button @click="startTimer(index)">开始</button>
<button @click="pauseTimer(index)">暂停</button>
<button @click="resetTimer(index)">重置</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
timers: [
{ remaining: 60, interval: null, isRunning: false },
{ remaining: 120, interval: null, isRunning: false },
{ remaining: 180, interval: null, isRunning: false }
]
}
},
methods: {
formatTime(seconds) {
const mins = Math.floor(seconds / 60)
const secs = seconds % 60
return `${mins}:${secs < 10 ? '0' : ''}${secs}`
},
startTimer(index) {
if (this.timers[index].isRunning) return
this.timers[index].isRunning = true
this.timers[index].interval = setInterval(() => {
if (this.timers[index].remaining > 0) {
this.timers[index].remaining--
} else {
clearInterval(this.timers[index].interval)
this.timers[index].isRunning = false
}
}, 1000)
},
pauseTimer(index) {
clearInterval(this.timers[index].interval)
this.timers[index].isRunning = false
},
resetTimer(index) {
this.pauseTimer(index)
this.timers[index].remaining = [60, 120, 180][index]
}
},
beforeDestroy() {
this.timers.forEach(timer => {
clearInterval(timer.interval)
})
}
}
</script>
使用计算属性优化显示
添加计算属性可以更好地管理时间格式显示:
computed: {
formattedTimers() {
return this.timers.map(timer => {
return {
...timer,
display: this.formatTime(timer.remaining)
}
})
}
}
使用Vuex管理全局状态
当需要跨组件共享倒计时状态时,可以使用Vuex:
// store.js
export default new Vuex.Store({
state: {
timers: []
},
mutations: {
UPDATE_TIMER(state, { index, remaining }) {
state.timers[index].remaining = remaining
},
SET_TIMER_INTERVAL(state, { index, interval }) {
state.timers[index].interval = interval
}
},
actions: {
startTimer({ commit, state }, index) {
const interval = setInterval(() => {
if (state.timers[index].remaining > 0) {
commit('UPDATE_TIMER', {
index,
remaining: state.timers[index].remaining - 1
})
} else {
clearInterval(state.timers[index].interval)
}
}, 1000)
commit('SET_TIMER_INTERVAL', { index, interval })
}
}
})
使用Composition API实现
在Vue 3中可以使用Composition API更简洁地实现:
import { ref, onUnmounted } from 'vue'
export default {
setup() {
const timers = ref([
{ remaining: 60, interval: null },
{ remaining: 120, interval: null },
{ remaining: 180, interval: null }
])
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60)
const secs = seconds % 60
return `${mins}:${secs < 10 ? '0' : ''}${secs}`
}
const startTimer = (index) => {
if (timers.value[index].interval) return
timers.value[index].interval = setInterval(() => {
if (timers.value[index].remaining > 0) {
timers.value[index].remaining--
} else {
clearInterval(timers.value[index].interval)
timers.value[index].interval = null
}
}, 1000)
}
onUnmounted(() => {
timers.value.forEach(timer => {
if (timer.interval) clearInterval(timer.interval)
})
})
return { timers, formatTime, startTimer }
}
}
注意事项
清除定时器非常重要,避免组件销毁后定时器继续运行导致内存泄漏。在beforeDestroy或onUnmounted钩子中清除所有定时器。
对于复杂场景,可以考虑使用第三方库如countdown.js或day.js来处理时间格式和计算。







