如何让多个通知提示排队显示而不是同时弹出?
最近在做订单系统时遇到个难题,用户频繁点击操作按钮会触发多个通知提示,但它们总是堆叠在一起看不清内容…
我用Vue写了个基础的通知组件,通过数组管理提示项,但排队逻辑有问题。比如连续点击三次按钮,三个提示应该依次显示,但实际上它们会同时出现几秒后一起消失。我试过用setTimeout控制显示时间,但效果还是不好:
{{ msg }}
export default {
data() {
return {
notifications: [],
timer: null
}
},
methods: {
showNotification() {
const newMsg = `订单${Date.now()}处理中`
this.notifications.push(newMsg)
if (!this.timer) {
this.timer = setTimeout(() => {
this.notifications.shift()
this.timer = null
}, 3000)
}
}
}
}
我发现当快速点击时,后添加的通知会覆盖之前的定时器,导致队列顺序被打乱。有没有更好的方式让通知像队列一样一个接一个显示?求大神指点具体实现方法!
常见的解决方案是使用异步队列机制,配合 Promise 和 setTimeout 来实现串行播放。你不需要一次性给所有通知设定时器,而是让队列按顺序逐个处理。
你可以改写逻辑如下:
这样每次点击都会把消息推进 queue,只有当前一个显示完后才会处理下一个。关键是用 async/await 配合 Promise 做异步等待,避免定时器冲突。
另外注意 DOM 渲染要基于 notifications 数组里的内容,建议每条通知带个唯一 id 更安全,防止重复文本导致删除错乱。比如可以用 Symbol 或 uuid 当 key。
核心就是:不要共享一个定时器,而是让队列主动控制流程,一个结束再下一个。这套模式在 toast、message 组件里非常通用,Element UI 和 Ant Design 都是这么干的。
核心思路是:每次只处理一个通知,等它显示完再递归处理下一个,而不是用一个定时器去控制所有通知。
改一下你的代码逻辑:
模板部分稍微调整下:
这样写的好处是每个通知都能按顺序显示,而且不会互相干扰。快速点击按钮时,通知会乖乖排队,一个接一个弹出来。
如果你还想加点动画效果,可以用Vue的过渡组件
<transition>,让通知进出更平滑。不过这是进阶功能,先解决基础问题再说。