如何实现Vue中v-for列表项按timer自动删除并支持悬停重置计时器
解决方案
你不需要维护定时器数组,直接新增一个和消息Map一一对应的定时器Map来管理每个消息的定时任务即可,查找和删除效率都是O(1),比数组更适配你的现有业务逻辑。
核心实现思路
- 新增
timerMap存储每个消息key对应的定时器ID,和现有messages的key一一对应 - 封装定时器启动、清除的公共方法,避免重复代码
- 新增消息时自动启动5秒倒计时
- 鼠标移入消息时清除当前定时器(实现重置效果)
- 鼠标移出消息时重新启动定时器(恢复计时)
- 删除消息前先清除对应定时器,避免内存泄漏
完整修改后代码
<!DOCTYPE html> <header> <script src="https://unpkg.com/vue@next"></script> </header> <body> <div class="messenger" id="app"> <div v-for="[key, msg] in messages" :key="key" @click="deleteMessage(key)" @mouseenter="handleMouseEnter(key)" @mouseleave="handleMouseLeave(key)" > {{ msg }} </div> </div> </body> <script> const app = { data() { return { messages: new Map([[0, "sdf"]]), timerMap: new Map(), // 存储每个消息对应的定时器ID i: 0, }; }, mounted() { // 初始化第一条消息的定时器 this.startTimer(0) window.authorizationMessage = function (msg) { const key = ++this.i this.messages.set(key, msg); // 新增消息后立即启动定时器 this.startTimer(key) }.bind(this); }, methods: { // 启动指定消息的倒计时 startTimer(key) { const timerId = setTimeout(() => { this.deleteMessage(key) }, 5000) this.timerMap.set(key, timerId) }, // 清除指定消息的倒计时 clearTimer(key) { if (this.timerMap.has(key)) { clearTimeout(this.timerMap.get(key)) this.timerMap.delete(key) } }, // 删除消息 deleteMessage(key) { this.clearTimer(key) this.messages.delete(key) }, // 鼠标移入:清除定时器重置计时 handleMouseEnter(key) { this.clearTimer(key) }, // 鼠标移出:重新启动定时器 handleMouseLeave(key) { this.startTimer(key) } } } Vue.createApp(app).mount('#app') </script>
拓展说明
如果后续需求调整为鼠标移入暂停计时、移出后从剩余时间继续,只需要再新增一个createTimeMap存储每个消息的创建时间,清除定时器时计算已走时长得到剩余时间,启动定时器时传入剩余时间代替固定的5000即可。
内容的提问来源于stack exchange,提问作者Gorilka
相关产品推荐
相关产品推荐

