#javascript #api #vue.js
#javascript #API #vue.js
Вопрос:
У меня есть API, возвращающий сообщения чата в следующем объекте.
messages : [
[
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-26",
date_group: "Today",
],
[
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-26",
date_group: "Today",
],
[
sender: "John Doe",
sent_at: "2020-09-26",
date_group: "Today",
],
[
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-25",
date_group: "Yesterday",
],
[
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-25",
date_group: "Yesterday",
],
[
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-24",
date_group: "Thursday",
],
]
Вместо фильтрации и группировки messages
по date_group
, а затем повторной сортировки по дате и отображению, я просто сравниваю текущее сообщение date_group
с предыдущим сообщением и, если date_group
оно отличается, печатаю его.
printDateGroup(messageKey) {
return this.messages[messageKey - 1] amp;amp; this.messages[messageKey].date_group !== this.messages[messageKey - 1].date_group
|| messageKey === 0;
},
Пока все работает нормально, но все сообщения теперь печатаются в одном div. Что вызывает проблемы с липкой позицией date_group
.
В настоящее время я печатаю их следующим образом.
<div class="d-flex flex-column message-wrapper">
<template v-for="(message, idx) in messages">
<div v-if="printDateGroup(idx)" class="date-label">
<span>{{ message.date_group }}</span>
</div>
<div class="message-text">{{message.text}}</div>
</template>
</div>
Вместо этого я хотел бы отобразить их по div
одному date_group
, как показано ниже.
<div class="d-flex flex-column message-wrapper">
<div class="date-wrapper">
<div class="date-label">Yesterday</div>
<div class="message-text">Some message</div>
<div class="message-text">Some message</div>
<div class="message-text">Some message</div>
</div>
<div class="date-wrapper">
<div class="date-label">Today</div>
<div class="message-text">Some message</div>
<div class="message-text">Some message</div>
<div class="message-text">Some message</div>
</div>
</div>
Я пытался открыть div, а не закрывать его, как мы делаем, php
но это не работает.
Ответ №1:
Вы не можете сделать это в vue, но вы можете реорганизовать свою модель данных.
Это пример компонента, который работает так, как вам нужно:
<template>
<div class="d-flex flex-column message-wrapper">
<template v-for="(group) in groups">
<div class="date-wrapper">
<div class="date-label">
{{ group.name }}
</div>
<div v-for="message in group.messages" class="message-text">{{message.text}}</div>
</div>
</template>
</div>
</template>
<script>
export default {
name: "index",
computed: {
messages() {
return [
{
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-26",
date_group: "Today",
},
{
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-26",
date_group: "Today",
},
{
sender: "John Doe",
sent_at: "2020-09-26",
date_group: "Today",
},
{
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-25",
date_group: "Yesterday",
},
{
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-25",
date_group: "Yesterday",
},
{
sender: "John Doe",
text: "Some message",
sent_at: "2020-09-24",
date_group: "Thursday",
},
]
},
groups() {
const res = [];
for (let i = 0; i < this.messages.length; i ) {
if (this.printDateGroup(i)) {
res.push({
name: this.messages[i].date_group,
messages: [this.messages[i]]
})
} else {
res[res.length - 1].messages.push(this.messages[i])
}
}
return res;
}
},
methods: {
printDateGroup(messageKey) {
return this.messages[messageKey - 1] amp;amp; this.messages[messageKey].date_group !== this.messages[messageKey - 1].date_group
|| messageKey === 0;
},
}
}
</script>
Причиной такого состояния является дизайн Vue.
Ответственность за моделирование данных лежит на стороне js, потребности в шаблонах содержат только простейшие операции, такие как for
или if
, но более продвинутая обработка должна выполняться в части компонентов js.
Комментарии:
1. ну да, я это сделал, но, как я уже сказал, если в чате 100 сообщений, он будет фильтроваться много времени, чего я пытаюсь избежать, но обязательно буду использовать этот подход в качестве последнего средства.
2. Вы можете наблюдать проблемы с эффективностью для 5k — 50k сообщений. Ниже этого уровня вы не должны видеть никаких проблем со временем рендеринга.