Функция получения имени месяца по его индексу, она нам ниже понадобится:
const getMonthName = iMonth =>
new Date(0, iMonth).toLocaleString('ru-RU', { month: 'long' });
Сгруппированные данные оформляем в виде вычисляемого свойства.
Бежим по массиву исходных данных, получаем имя месяца, создаём в результирующем объекте массив группы, если таковой отсутствует, добавляем в него текущий элемент.
Вот так всё просто:
computed: {
groupedByMonth() {
return this.items.reduce((acc, n) => {
const key = getMonthName(n.date.split('-')[1] - 1);
(acc[key] = acc[key] || []).push(n);
return acc;
}, {});
},
},
<ul>
<li v-for="(items, month) in groupedByMonth" :key="month">
<h3>{{ month }}</h3>
<ul>
<li v-for="n in items" :key="n.id">{{ n }}</li>
</ul>
</li>
</ul>
Если нужны все месяцы, в том числе и те, за которые нет никаких данных, тогда сразу создаём массив на двенадцать элементов, каждый из которых содержит имя месяца и массив для сгруппированных данных. Бежим по исходному массиву, получаем индекс месяца, кладём текущий элемент в массив соответствующей группы.
Тоже ничего сложного:
groupedByMonth() {
return this.items.reduce((acc, n) => {
acc[n.date.split('-')[1] - 1].items.push(n);
return acc;
}, Array.from({ length: 12 }, (_, i) => ({
month: getMonthName(i),
items: [],
})));
},
<ul>
<li v-for="{ items, month } in groupedByMonth" :key="month">
<h3>{{ month }}</h3>
<ul v-if="items.length">
<li v-for="n in items" :key="n.id">{{ n }}</li>
</ul>
<div v-else>данных нет</div>
</li>
</ul>