предисловие
Когда мы общаемся на QQ, записи чата за одну и ту же минуту будут отображаться вместе.Когда мы отправляем сообщения, время отправки каждого сообщения будет с точностью до секунды, так как же он делит эти данные на минуты?Что это показывает ?
Сегодня, когда я добавил отображение времени отправки сообщения в запись чата моего проекта с открытым исходным кодом, я столкнулся с этой проблемой.Сначала я не понимал, как быть с этими данными.Потом, после некоторых размышлений, я, наконец, возникла идея ее реализации и реализована. , в этой статье я поделюсь с вами своими идеями и процессом реализации, приглашаю всех заинтересованных разработчиков прочитать эту статью.
Давайте посмотрим на окончательный результат:
Реализовать идеи
Давайте сначала посмотрим на мои данные, а именно:
[{
"createTime": "2020-12-21 20:58:19",
"avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg",
"msgId": "121710f399b84322bdecc238199d6888",
"msgText": "/坏笑/",
"userName": "神奇的程序员",
"userId": "c04618bab36146e3a9d3b411e7f9eb8f",
"status": false
}, {
"createTime": "2020-12-21 20:58:22",
"avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg",
"msgId": "121710f399b84322bdecc238199d6888",
"msgText": "还有人吗",
"userName": "神奇的程序员",
"userId": "c04618bab36146e3a9d3b411e7f9eb8f",
"status": false
}, {
"createTime": "2020-12-21 20:58:46",
"avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg",
"msgId": "121710f399b84322bdecc238199d6888",
"msgText": "聊天记录,添加了消息发送时间",
"userName": "神奇的程序员",
"userId": "c04618bab36146e3a9d3b411e7f9eb8f",
"status": false
}, {
"createTime": "2020-12-21 20:58:52",
"avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg",
"msgId": "121710f399b84322bdecc238199d6888",
"msgText": "现在看起来就方便多了",
"userName": "神奇的程序员",
"userId": "c04618bab36146e3a9d3b411e7f9eb8f",
"status": false
}, {
"createTime": "2020-12-21 21:35:27",
"avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg",
"msgId": "121710f399b84322bdecc238199d6888",
"msgText": "/坏笑/",
"userName": "神奇的程序员",
"userId": "c04618bab36146e3a9d3b411e7f9eb8f",
"status": false
}]
Глядя на приведенные выше данные, мы обнаруживаем, что каждый объект сообщения имеетcreateTimeАтрибут, это время отправки сообщения с точностью до часов, минут и секунд, теперь нам нужно сохранить только одно время одной и той же минуты.createTimeАтрибут, при рендеринге время имеет только рендерингcreateTimeобъекта свойства, чтобы одни и те же минуты данных отображались вместе.
Общая идея такова, давайте посмотрим на конкретную идею:
- объявляет объект с именем
timeObj, хранится в объекте сообщенияcreateTimeполеГод-Месяц-День Час:Минута, объявляет новый массив записей сообщенийfinalTextListХранить обработанные данные - Пройдите массив записей сообщений, чтобы получить текущий пройденный объект записи сообщения.
- Получить пройденный объект записи сообщения
createTimeатрибут, перехватГод-Месяц-День Час:Минута, объявить переменнуюtimeсохранить - судить
timeСуществует ли вtimeObjсередина - Если он существует, удалите пройденный объект записи сообщения в
createTimeатрибут, поместите объект записи сообщения после удаления атрибута вfinalTextListсередина - иначе будет
timeпоставить как атрибутtimeObj, поместите пройденный объект записи сообщения вfinalTextListсередина
После обработки данных мы оцениваем, существует ли текущий элемент рендеринга при рендеринге.createTime, который отображается, если он существует.
Процесс реализации
Далее, после того, как мы получим данные, возвращаемые интерфейсом, мы обрабатываем их в соответствии с вышеизложенными идеями.
Обработка данных, возвращаемых интерфейсом
Следующим образомres.data.messageTextListСписок записей сообщений, возвращаемых для интерфейса.
// 消息内容列表
const messageTextList: Array<msgListType> = res.data.messageTextList;
// 处理好的消息内容数组
const finalTextList: Array<msgListType> = [];
// 时间存放对象
const timeObj: { [key: string]: boolean } = {};
// 处理消息内容列表,同一分钟的数据只保留一个创建时间
for (let i = 0; i < messageTextList.length; i++) {
// 消息对象
const messageObj = messageTextList[i];
// 获取时间的 年-月-日 时:分
const time = (messageObj.createTime as string).substring(0, 16);
// timeObj中已经存在time,则移除当前消息对象的createTime
if (_.has(timeObj, time)) {
// 移除createTime属性
_.unset(messageObj, "createTime");
// 将移除createTime属性的消息对象放进处理好的消息数组中
finalTextList.push(messageObj);
} else {
// 将time作为key放进timeObj中
timeObj[time] = true;
// 原封不动的将消息对象放进处理好的消息数组中
finalTextList.push(messageObj);
}
}
// 渲染消息列表
this.renderPage(finalTextList, {});
в приведенном выше коде
msgListTypeОпределение типа для объекта записи сообщения имеет значениеlodashМетод используется для определения того, содержит ли объект определенный атрибут, а также не установлен.lodashметод используется для удаления свойства из объекта.
Обрабатывать push-данные
При получении данных, отправленных сервером, нам нужно агрегировать сообщения, отправленные сервером, в уже обработанные записи чата.Если сообщения не в ту же минуту, будет отображаться новое время, поэтому нам нужно удалить текущее push-сообщение.createTimeполе, перехватГод-Месяц-День Час:МинутаОпределить, находится ли оно в списке записей отображаемых сообщений, если оно не существует, оно будет отображаться как есть, в противном случае оно будет удалено.createTimeПосле отображения поля код выглядит следующим образом:
// 接收到服务端推送的新消息,渲染单个消息对象
const thisSenderMessageObj: msgListType = {
msgText: msgObj.msgText,
avatarSrc: msgObj.avatarSrc,
userId: msgObj.userId,
userName: msgObj.userName,
createTime: msgObj?.createTime
};
// 找到消息记录列表中与新消息的同一分钟的消息,移除新消息的createTime对象
for (let i = 0; i < this.senderMessageList.length; i++) {
const messageObj: msgListType = this.senderMessageList[i];
// 截取当前消息与新消息发送时间的 年-月-日 时:分,判断其是否相等
if (_.isEqual( messageObj.createTime?.substring(0,16),thisSenderMessageObj.createTime?.substring(0, 16))) {
// 移除新消息的createTime属性
_.unset(thisSenderMessageObj, "createTime");
}
}
// 解析并渲染
this.messageParsing(thisSenderMessageObj);
msgObj — это сообщение, отправленное сервером
визуализировать страницу
Далее, давайте посмотрим на код рендеринга страницы, как показано ниже, только объект рендеринга содержитcreateTimeатрибутивные данные
<!--消息发送时间-->
<div class="snder-time-panel" v-if="item.createTime">
<span>{{ item.createTime.substring(5, 16) }}</span>
</div>
Оптимизация рендеринга
Спасибо за раздел комментариев@leeing, мой метод реализации заключается в непосредственном изменении типа данных.При рендеринге новых данных я должен каждый раз сравнивать уже отрендеренные данные.时间复杂度是O(n).
После использования идеи копания друзей временная сложность напрямую снижается с O(n) до O(1)😄, код выглядит следующим образом:
<!--消息发送时间:当前发送消息为第一条显示时间-->
<div class="sender-time-panel" v-if="index === 0">
<span>{{ item.createTime.substring(11, 16) }}</span>
</div>
<!--当前消息与上一条消息发送时间截取时分进行相减大于1就显示时间-->
<div
class="sender-time-panel"
v-else-if="
parseInt(
item.createTime.substring(11, 13) +
item.createTime.substring(14, 16)
) -
parseInt(
senderMessageList[index - 1].createTime.substring(11, 13) +
senderMessageList[index - 1].createTime.substring(14, 16)
) >
1
"
>
<span>{{ item.createTime.substring(11, 16) }}</span>
</div>
добиться эффекта
Наконец, давайте посмотрим на достигнутый эффект, а именно:
Давайте отправим еще одно сообщение, чтобы увидеть эффект, как показано ниже:
адрес проекта
Кодовый адрес:message-display.vue
Адрес онлайн-опыта:chat-system
напиши в конце
- Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь 😊
- Эта статья была впервые опубликована на Наггетс, перепечатка без разрешения запрещена 💌