Vue.js中过滤数据后latestfinalData始终为空数组的问题
问题:无法筛选出5000毫秒内更新的记录
我要开发一个数据更新时触发提示音并播报更新数据ID的应用。目前已实现每1000毫秒检查一次数据库,筛选5000毫秒内更新的记录来触发提示音,但latestfinalData.value始终打印空数组,finalData.value能正常打印包含多个元素的数组,无报错信息。预期latestfinalData.value输出非空数组,用于后续触发提示音。
完整代码
<script setup> import { ref, onMounted } from 'vue'; import axios from 'axios'; const collection1Data = ref([]); const collection2Data = ref([]); const fetchData = async () => { const [collection1Response, collection2Response] = await Promise.all([ axios.get('https://koh-abx.com:50100/onboardshows'), axios.get('https://koh-abx.com:50100/onboardlands'), ]); collection1Data.value = collection1Response.data; collection2Data.value = collection2Response.data; }; const finalData = ref([]); const latestfinalData = ref([]); onMounted(async () => { await fetchData(); setInterval(() => { fetchData().then(() => { finalData.value = []; collection1Data.value.forEach(doc1 => { const matchingDoc = collection2Data.value.find(doc2 => doc1.idshow === doc2.idshow); if (matchingDoc) { finalData.value.push({ idshow: doc1.idshow, numbershow: doc1.updatedAt > matchingDoc.updatedAt ? doc1.numbershow : matchingDoc.numbershow, ab: doc1.updatedAt > matchingDoc.updatedAt ? doc1.ab : matchingDoc.ab, updatedAt: doc1.updatedAt > matchingDoc.updatedAt ? doc1.updatedAt : matchingDoc.updatedAt }); } else { finalData.value.push({ idshow: doc1.idshow, numbershow: doc1.numbershow, ab: doc1.ab, updatedAt: doc1.updatedAt }); } }); collection2Data.value.forEach(doc2 => { if (!finalData.value.find(doc => doc.idshow === doc2.idshow)) { finalData.value.push({ idshow: doc2.idshow, numbershow: doc2.numbershow, ab: doc2.ab, updatedAt: doc2.updatedAt }); } }); console.log(finalData.value); latestfinalData.value = finalData.value.filter(doc => doc.updatedAt >= (Date.now() - 5000)); console.log(latestfinalData.value); }); }, 1000); }); </script>
问题原因与解决办法
核心问题:updatedAt格式不匹配
Date.now()返回的是毫秒级时间戳(数字类型),但后端返回的updatedAt大概率是ISO字符串(例如"2024-05-20T12:34:56.789Z")或非毫秒级时间戳,直接用>=比较会导致逻辑失效,无法筛选出符合条件的记录。
解决步骤
统一时间格式:将后端返回的
updatedAt转换为毫秒级时间戳后再比较,修改筛选逻辑:latestfinalData.value = finalData.value.filter(doc => { // 将updatedAt转为毫秒时间戳 const updateTime = typeof doc.updatedAt === 'string' ? new Date(doc.updatedAt).getTime() : Number(doc.updatedAt); return updateTime >= (Date.now() - 5000); });验证时间转换正确性:在
console.log(finalData.value)后添加日志,确认转换是否正常:console.log('当前时间戳:', Date.now()); console.log('5秒前时间戳:', Date.now() - 5000); finalData.value.forEach(doc => { console.log(`idshow: ${doc.idshow}, updatedAt原始值: ${doc.updatedAt}, 转换后时间戳: ${typeof doc.updatedAt === 'string' ? new Date(doc.updatedAt).getTime() : Number(doc.updatedAt)}`); });优化数据合并逻辑(可选):当前合并两个集合数据的方式可简化,避免重复遍历:
// 用Map存储idshow对应的最新数据 const dataMap = new Map(); // 先处理collection1Data collection1Data.value.forEach(doc1 => { dataMap.set(doc1.idshow, { idshow: doc1.idshow, numbershow: doc1.numbershow, ab: doc1.ab, updatedAt: doc1.updatedAt }); }); // 处理collection2Data,保留更新时间更晚的记录 collection2Data.value.forEach(doc2 => { const existing = dataMap.get(doc2.idshow); if (!existing || new Date(doc2.updatedAt).getTime() > new Date(existing.updatedAt).getTime()) { dataMap.set(doc2.idshow, { idshow: doc2.idshow, numbershow: doc2.numbershow, ab: doc2.ab, updatedAt: doc2.updatedAt }); } }); // 转换为数组 finalData.value = Array.from(dataMap.values());
内容的提问来源于stack exchange,提问作者Nopmd
相关产品推荐
相关产品推荐

