Вот что происходит ...
У метода displayPostDate
есть побочный эффект обновления реактивной зависимости (т. Е. Он обновляет datesDone[]
), что вызывает другой цикл рендеринга, который вызываетметод снова.
Например, скажем, у вас есть пустой datesDone[]
и четыре элемента в messages[]
, каждый с уникальными created_at
датами.
- При первоначальном рендеринге
displayPostDate
не находит даты created_at
в своем datesDone[]
, поэтому добавляет их в массив.Он также возвращает true
для отображения span
s. - Vue обнаруживает изменение в
datesDone[]
- зависимость displayPostDate
, поэтому он запускает другой цикл рендеринга. - При втором рендеринге
displayPostDate
находит все даты в datesDone[]
, поэтому никаких изменений в datesDone[]
не происходит.Он также возвращает false
, чтобы скрыть span
s.Поскольку зависимость не изменилась, Vue не выполняет повторную визуализацию.
Вот как это исправить ...
Во-первых, обратите внимание, что для вызова метода в шаблоне используется неэффективно , поскольку он вызывается каждый раз при визуализации шаблона, что может происходить несколько раз, что, в свою очередь, требует, чтобы метод был идемпотентным (и не изменял свои реактивные зависимости), чтобы избежать цикла рендеринга.
ToДля решения этой проблемы более простым решением является предварительная фильтрация списка, чтобы он включал только те элементы, которые вы хотите отобразить (вместо условного отображения в шаблоне).Это дает дополнительное преимущество, заключающееся в упрощении шаблона и устранении необходимости в datesDone[]
, при условии, что он не имеет другого использования, кроме как для отслеживания дубликатов.Я рекомендую создать этот список как вычисляемое свойство , чтобы результат кэшировался и не подвергался ненужной повторной оценке в другом цикле рендеринга:
// script
computed: {
uniqueMessages() {
const uniq = this.messages.reduce((c, msg) => {
c[msg.created_at] = c[msg.created_at] || msg
return c
}, {})
return Object.values(uniq)
}
}
// template
<div v-for="message in uniqueMessages">
<span class="grouped-date">
{{ message.created_at }}
</span>
</div>
demo