Vue.js中如何按日期排序展示两个数组的消息数据
通讯消息按日期排序展示问题及解决方案
我给客户开发了一款类LiveChat的应用,目前已实现消息收发并在网页展示功能,但当前消息是先展示所有收到的消息,再展示所有发送的消息。需要改成像主流通讯应用那样,按日期排序展示所有消息,无论消息是接收还是发送的。
尝试过创建新数组将收发消息都推入,但未成功。当前的数据结构如下:
- Conversation[](主数组)
- received[](对象数组)→ specific_messages{}(包含数据的对象)
- sended[](对象数组)→ specific_messages{}(包含数据的对象)
希望遍历数组时,若specific_message对象包含direction = incoming,则调用Incoming Message Component,否则调用Outgoing Message Component,但多种尝试均未奏效。
相关代码
接收消息代码
getSmsContent(){ var mapURL; var smsContent = []; for (let i = 0; i < this.getSMS.length; i++) { if (this.getSMS[i].sender == this.get_sms_sender) { mapURL = this.getSMS[i].url_gps; if (this.getSMS[i].message.length == 1) { smsContent.push(this.getSMS[i].message); } else { for (let j = 0; j < this.getSMS[i].message.length; j++) { smsContent.push(this.getSMS[i].message[j]); } } } } this.mapURL = mapURL; this.smsContent = smsContent; this.conversation.push(smsContent); },
发送消息代码
loadLastSMS(){ const lastSMS = []; SMSService.getLastSMS() //TODO //this needs to be ordered by date .then((response) => { const data = response.data.result; let objectID = []; for (let key in data) { objectID.push(key); } var last_sms = []; for (let i = 0; i < objectID.length; i++) { last_sms.push(response.data.result[objectID[i]]); } for (let j = 0; j < last_sms.length; j++) { lastSMS.push({ date_time: last_sms[j].date_time, message: last_sms[j].message, recipient: last_sms[j].recipient, sender: last_sms[j].sender, stat: last_sms[j].stat, status_id: last_sms[j].status_id, type: last_sms[j].type, url_gps: last_sms[j].url_gps, }); } this.lastSMS = lastSMS; this.conversation.push(lastSMS); }); }
Vue.js页面代码
<div v-for="content in conversation" :key="content.id"> <section v-if="content.direction == 'incoming'"> <IncomingChatCard :content="content" :mapURL="mapURL" /> </section> <section v-else> <OutgoingChatCard :item="sms" /> </section> </div>
当前conversation数组状态
控制台截图显示:主数组conversation内包含两个子数组,分别存储接收和发送的消息集合,每个子数组内是具体的消息对象,但未包含direction标识字段。
解决方案
1. 统一消息格式,添加方向标识
首先修改接收和发送消息的方法,给每条消息添加direction字段,并确保每条消息都带有日期信息:
修改接收消息方法
getSmsContent(){ var mapURL; var smsContent = []; for (let i = 0; i < this.getSMS.length; i++) { if (this.getSMS[i].sender == this.get_sms_sender) { mapURL = this.getSMS[i].url_gps; // 统一处理单条/多条消息 const messages = Array.isArray(this.getSMS[i].message) ? this.getSMS[i].message : [this.getSMS[i].message]; // 给每条消息添加方向、日期等必要字段 messages.forEach(msg => { smsContent.push({ ...msg, direction: 'incoming', date_time: this.getSMS[i].date_time, // 从父级取日期,需确保原数据有该字段 url_gps: mapURL }); }); } } this.mapURL = mapURL; this.smsContent = smsContent; },
修改发送消息方法
loadLastSMS(){ SMSService.getLastSMS() .then((response) => { const data = response.data.result; // 直接转成数组并添加方向标识 const lastSMS = Object.values(data).map(item => ({ ...item, direction: 'outgoing' })); this.lastSMS = lastSMS; }); }
2. 合并消息并按日期排序
创建Vue计算属性,合并接收和发送的消息数组,然后按date_time排序:
computed: { sortedMessages() { // 合并所有消息 const allMessages = [...this.smsContent, ...this.lastSMS]; // 按日期排序,若date_time是字符串需转为Date对象 return allMessages.sort((a, b) => new Date(a.date_time) - new Date(b.date_time)); } }
3. 修改页面渲染逻辑
直接遍历排序后的消息数组,根据direction渲染对应组件:
<div v-for="(msg, index) in sortedMessages" :key="index"> <section v-if="msg.direction === 'incoming'"> <IncomingChatCard :content="msg" :mapURL="msg.url_gps" /> </section> <section v-else> <OutgoingChatCard :item="msg" /> </section> </div>
关键注意点
- 确保所有消息都有统一的日期字段,如果原接收消息的日期在父级对象中,必须将其挂载到每条消息上。
- 排序时注意日期格式,若
date_time是字符串类型,必须转换为Date对象才能正确比较时间先后。 - 原
conversation数组是嵌套结构,现在改为扁平化的消息对象数组,才能实现按日期全局排序。
内容的提问来源于stack exchange,提问作者Marek
相关产品推荐
相关产品推荐

