Vue中定时移除对象数组FINISH状态记录并解决重复显示问题
解决方案
针对你遇到的问题,核心原因是每次刷新数据时都会重新将包含FINISH状态的完整数据赋值给turns,同时旧的定时器可能还会干扰新数据的展示逻辑。下面提供两种适配不同需求的解决方案:
需求一:每次刷新数据后仍先展示所有记录,6秒后移除FINISH项
这种方案保留“每次刷新都先全量展示,再定时过滤”的逻辑,同时避免定时器冲突:
- 添加定时器引用变量:在组件
data中声明变量保存定时器ID,用于后续清除旧定时器
data() { return { turns: [], selected: "", finishTimer: null // 存储过滤操作的定时器ID }; }
- 修改
getTurns方法:每次请求前清除旧定时器,避免旧逻辑干扰新数据;仅在存在FINISH项时设置一次定时器
getTurns() { // 清除上一次未执行的过滤定时器 if (this.finishTimer) { clearTimeout(this.finishTimer); this.finishTimer = null; } fetch("ENPOINT", { method: "POST", body: JSON.stringify({ id: this.selected }), headers: { "Content-Type": "application/json" } }) .then(response => response.json()) .then(data => { // 先展示所有获取到的数据 this.turns = data; // 检查是否存在FINISH状态的记录,仅在有需要时设置定时器 const hasFinishItems = data.some(item => item.status === "FINISH"); if (hasFinishItems) { this.finishTimer = setTimeout(() => { this.turns = this.turns.filter(item => item.status !== "FINISH"); }, 6000); } }) .catch(error => console.error(error)); }
- 组件销毁时清理定时器:避免内存泄漏
mounted() { this.getTurns(); this.refreshInterval = setInterval(() => { this.getTurns(); }, 5000); }, beforeUnmount() { // 清除过滤定时器和刷新间隔器 if (this.finishTimer) clearTimeout(this.finishTimer); if (this.refreshInterval) clearInterval(this.refreshInterval); }
需求二:FINISH项展示6秒后,后续刷新不再显示该记录
如果希望某个FINISH记录被移除后,即使后续刷新数据中仍存在该记录也不再展示,可以通过记录已处理的FINISH项ID实现:
- 添加已处理ID集合:在
data中用Set存储已处理的FINISH项ID,保证查询效率
data() { return { turns: [], selected: "", finishTimer: null, processedFinishIds: new Set() // 存储已处理过的FINISH项ID }; }
- 修改
getTurns方法:请求数据时先过滤已处理的FINISH项,再设置定时器处理新的FINISH项
getTurns() { if (this.finishTimer) { clearTimeout(this.finishTimer); this.finishTimer = null; } fetch("ENPOINT", { method: "POST", body: JSON.stringify({ id: this.selected }), headers: { "Content-Type": "application/json" } }) .then(response => response.json()) .then(data => { // 过滤掉已经处理过的FINISH项,避免重复展示 const filteredData = data.filter(item => { return !(item.status === "FINISH" && this.processedFinishIds.has(item.id)); }); this.turns = filteredData; // 收集本次数据中未处理的FINISH项ID const newFinishIds = filteredData .filter(item => item.status === "FINISH" && !this.processedFinishIds.has(item.id)) .map(item => item.id); if (newFinishIds.length > 0) { this.finishTimer = setTimeout(() => { // 将新的FINISH项ID标记为已处理 newFinishIds.forEach(id => this.processedFinishIds.add(id)); // 移除已处理的FINISH项 this.turns = this.turns.filter(item => !this.processedFinishIds.has(item.id)); }, 6000); } }) .catch(error => console.error(error)); }
- 组件销毁时清理资源:同样需要在
beforeUnmount中清除定时器和间隔器,代码同需求一的beforeUnmount部分。
内容的提问来源于stack exchange,提问作者Desarrollador
相关产品推荐
相关产品推荐

