Vue2中如何实现可重置倒计时的自动关闭<b-alert>?
Vue2 可重置倒计时的实现方案
核心思路
将每个通知的状态(消息内容、剩余倒计时、定时器)独立维护,用数组存储所有活跃通知,针对相同消息做倒计时重置,不同消息新增通知实例,彻底避免定时器冲突问题。
具体实现代码
1. EventBus 定义
// event-bus.js import Vue from 'vue' export const EventBus = new Vue()
2. 通知组件代码
<template> <div class="notification-container"> <b-alert v-for="notification in notifications" :key="notification.id" :show="true" :variant="notification.variant || 'info'" dismissible @dismissed="removeNotification(notification.id)" > {{ notification.message }} <small class="ml-2">剩余 {{ notification.remainingTime }} 秒关闭</small> </b-alert> </div> </template> <script> import { EventBus } from './event-bus' export default { data() { return { notifications: [] } }, created() { EventBus.$on('show-notification', (payload) => { const { message, variant = 'info' } = payload this.handleNotification(message, variant) }) }, beforeDestroy() { this.notifications.forEach(notify => { clearInterval(notify.timerId) }) EventBus.$off('show-notification') }, methods: { handleNotification(message, variant) { const existingNotify = this.notifications.find(n => n.message === message) if (existingNotify) { clearInterval(existingNotify.timerId) existingNotify.remainingTime = 6 existingNotify.timerId = this.startCountdown(existingNotify.id) } else { const newNotify = { id: Date.now() + Math.random(), message, variant, remainingTime: 6, timerId: null } newNotify.timerId = this.startCountdown(newNotify.id) this.notifications.push(newNotify) } }, startCountdown(notifyId) { return setInterval(() => { const notify = this.notifications.find(n => n.id === notifyId) if (notify) { notify.remainingTime-- if (notify.remainingTime <= 0) { this.removeNotification(notifyId) } } }, 1000) }, removeNotification(notifyId) { const notifyIndex = this.notifications.findIndex(n => n.id === notifyId) if (notifyIndex !== -1) { clearInterval(this.notifications[notifyIndex].timerId) this.notifications.splice(notifyIndex, 1) } } } } </script> <style scoped> .notification-container { position: fixed; top: 20px; right: 20px; z-index: 9999; width: 350px; } .b-alert { margin-bottom: 10px; } </style>
3. 使用方式(其他组件中触发通知)
// 在任意组件中 import { EventBus } from './event-bus' // 触发普通通知 EventBus.$emit('show-notification', { message: '操作成功!', variant: 'success' }) // 触发相同消息的通知(会重置倒计时) EventBus.$emit('show-notification', { message: '操作成功!' })
关键修复点(针对你的问题)
- 独立定时器:每个通知拥有专属定时器,重置时先清除旧定时器再启动新的,避免多个定时器同时修改同一个倒计时变量,解决
bannerCountDown频繁调用的问题。 - 状态隔离:用数组存储每个通知的独立状态,相同消息只修改已有项的倒计时,不同消息新增项,满足多通知显示需求。
- 内存泄漏防护:组件销毁时清除所有定时器并解绑事件监听,通知关闭时也清除对应定时器。
内容的提问来源于stack exchange,提问作者cwbusacker
相关产品推荐
相关产品推荐

