Метод в компоненте
<template>
<div>
<div class="row flex-nowrap test">
<div v-if="halls" v-for="hall in halls" class="col-3 col-lg-3">
<div class="card">
<div class="card-body">
<a href="#" @click.prevent="getHallAtributes(hall.id)">{{ hall.name }}</a>
<span class="badge badge-primary ml-3 mb-2">5</span>
<i @click="showCalendar(hall.id)" class="pointer fe fe-calendar h2 ml-3 mb-0 text-muted"></i>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<table class="table table-bordered datatable datatable-User table-collection">
<tbody>
<tr>
<td class="pt-2 pb-2 col-3 text-center h3">
{{ this.monthNames[new Date(this.year, this.month).getMonth() - 1] }}, {{ this.year }}
</td>
<td v-for="n in dates" :style="[n.getDay() === 0 || n.getDay() === 6 ? { 'background-color': 'red', color: 'white' } : { color: 'black' },]" class="pt-2 pb-2 text-center">{{ n.getDate() }}
</td>
</tr>
<template v-for="val in hall.schedule_hall">
<tr>
<td class="bg-primary text-white">{{ val.time }}:00 - {{ val.programm.name }}
<i class="fe fe-plus ml-4"></i>
</td>
</tr>
<template v-for="vals in val.programm.children">
{{ computedUserData([vals]) }}
<tr v-for="user in selectedUsers" :key="user.id">
<td class="pt-2 pb-2 col-3">
<span class="ml-3">{{ user.surname }}</span>
<span class="ml-1">{{ user.name }}</span>
<span class="ml-4">{{ user.year }}</span>
</td>
<td v-for="(n, index) in daysInMonth" class="pt-2 pb-2 text-center order-left-0 border-white grey">
<i v-if="user.journal[n]" :class="user.journal[n]"></i>
</td>
</tr>
</template>
</template>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selectedUsers: [],
options: [
{ value: 'A', text: 'Option A (from options prop)' },
{ value: 'B', text: 'Option B (from options prop)' }
],
monthNames: [
"Январь", "Февраль", "Март", "Апрель", "Май", "Июнь",
"Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"
],
days: [
"Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"
],
programms: [
"Зирка Лева", "Вперед до зирок", "Мастер команды"
],
time: [
"1", "2", "3", "4"
],
halls: [],
children: [],
child: '',
hall: {
schedule_hall: {},
programm: {},
},
namegroup: '',
programm_id: '',
category_time: '',
dataVm: '',
n: 8,
year: 2020,
month: 6,
row: null,
rowid: null,
}
},
created() {
this.getHalls();
},
computed: {
daysInMonth(month,year) {
return new Date(this.year, this.month, 0).getDate();
},
dates() {
return new Array(this.daysInMonth).fill(1).map((_, index) => new Date(this.year, this.month - 1, index + 1))
}
},
methods: {
computedUserData(vals) {
this.selectedUsers = vals.reduce((res, item) => {
const tempItem = {
id: item.id,
surname: item.child_surname,
name: item.child_name,
journal: {}
}
tempItem.journal = item.journal.reduce((carry, {day, icon}) => {
carry[day] = icon;
return carry;
}, {});
res.push(tempItem)
return res;
}, []);
},
// Получаем список существующих залов и при условии наличии узнаем id первого элемента из массива и передаем параметр в метод
getHalls() {
axios.get('api/v2/halls')
.then(response => this.halls = response.data.data)
if (this.halls) {
setTimeout(() => {
this.halls ? this.getHallAtributes(this.halls[0].id) : null;
},500)
}
},
// Запускаем эмулятор загрузки, получаем атрибуты зала по его id
getHallAtributes(hall) {
let loader = this.$loading.show({
container: this.fullPage ? null : this.$refs.formContainer,
color: '#0080ff',
});
axios.get('api/v2/halls/' + hall)
.then(response => this.hall = response.data.data)
setTimeout(() => {
loader.hide()
},500)
},
}
}
</script>
Вот что приходит в hall
{
"id": 1,
"branch_id": 1,
"name": "Большой зал",
"created_at": null,
"updated_at": "2020-06-16 10:27:36",
"schedule_hall": [
{
"id": 1,
"hall_id": 1,
"programm_id": 2,
"day": 1,
"time": 8,
"category_time": 1,
"total_children": 20,
"created_at": null,
"updated_at": null,
"programm": {
"id": 2,
"name": "Вперед до зірок",
"branch_id": 1,
"created_at": "2020-05-20 18:33:12",
"updated_at": "2020-05-22 23:39:30",
"children": [
{
"id": 14,
"child_surname": "Турцевич",
"child_name": "Артём",
"programm_id": 2,
"journal": [
{
"id": 1,
"base_id": 14,
"day": 16,
"icon": "fe fe-alert-circle text-warning",
"created_at": null,
"updated_at": null
},
{
"id": 2,
"base_id": 14,
"day": 20,
"icon": "fe fe-sun text-primary",
"created_at": null,
"updated_at": null
},
{
"id": 5,
"base_id": 14,
"day": 11,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 06:45:29",
"updated_at": "2020-06-22 06:45:29"
},
{
"id": 29,
"base_id": 14,
"day": 30,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:52:24",
"updated_at": "2020-06-22 12:52:24"
},
{
"id": 42,
"base_id": 14,
"day": 1,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 13:22:34",
"updated_at": "2020-06-22 13:22:34"
}
]
},
{
"id": 16,
"child_surname": "Григорян",
"child_name": "Эдмон",
"programm_id": 2,
"journal": [
{
"id": 3,
"base_id": 16,
"day": 5,
"icon": "fe fe-x text-danger",
"created_at": null,
"updated_at": null
},
{
"id": 30,
"base_id": 16,
"day": 30,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:52:25",
"updated_at": "2020-06-22 12:52:25"
},
{
"id": 34,
"base_id": 16,
"day": 26,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:52:54",
"updated_at": "2020-06-22 12:52:54"
}
]
},
{
"id": 17,
"child_surname": "Сильченко",
"child_name": "Максим",
"programm_id": 2,
"journal": [
{
"id": 31,
"base_id": 17,
"day": 30,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:52:27",
"updated_at": "2020-06-22 12:52:27"
},
{
"id": 43,
"base_id": 17,
"day": 10,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 13:23:11",
"updated_at": "2020-06-22 13:23:11"
},
{
"id": 46,
"base_id": 17,
"day": 19,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 13:24:39",
"updated_at": "2020-06-22 13:24:39"
}
]
},
{
"id": 19,
"child_surname": "Соколовская",
"child_name": "София",
"programm_id": 2,
"journal": [
{
"id": 28,
"base_id": 19,
"day": 24,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:51:15",
"updated_at": "2020-06-22 12:51:15"
},
{
"id": 32,
"base_id": 19,
"day": 30,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:52:28",
"updated_at": "2020-06-22 12:52:28"
},
{
"id": 35,
"base_id": 19,
"day": 14,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:53:08",
"updated_at": "2020-06-22 12:53:08"
},
{
"id": 44,
"base_id": 19,
"day": 19,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 13:23:45",
"updated_at": "2020-06-22 13:23:45"
}
]
},
{
"id": 21,
"child_surname": "Иванов",
"child_name": "Дмитрий",
"programm_id": 2,
"journal": [
{
"id": 26,
"base_id": 21,
"day": 1,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:50:17",
"updated_at": "2020-06-22 12:50:17"
},
{
"id": 27,
"base_id": 21,
"day": 1,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:50:41",
"updated_at": "2020-06-22 12:50:41"
},
{
"id": 33,
"base_id": 21,
"day": 30,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:52:29",
"updated_at": "2020-06-22 12:52:29"
},
{
"id": 36,
"base_id": 21,
"day": 8,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:54:02",
"updated_at": "2020-06-22 12:54:02"
}
]
}
]
}
},
{
"id": 2,
"hall_id": 1,
"programm_id": 3,
"day": 1,
"time": 10,
"category_time": 7,
"total_children": 12,
"created_at": null,
"updated_at": null,
"programm": {
"id": 3,
"name": "Народження зірки",
"branch_id": 1,
"created_at": "2020-05-20 18:33:23",
"updated_at": "2020-05-22 23:39:11",
"children": [
{
"id": 22,
"child_surname": "Шевченко",
"child_name": "Максим",
"programm_id": 3,
"journal": [
{
"id": 37,
"base_id": 22,
"day": 24,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:54:46",
"updated_at": "2020-06-22 12:54:46"
},
{
"id": 38,
"base_id": 22,
"day": 1,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:54:50",
"updated_at": "2020-06-22 12:54:50"
},
{
"id": 39,
"base_id": 22,
"day": 11,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 12:55:47",
"updated_at": "2020-06-22 12:55:47"
},
{
"id": 40,
"base_id": 22,
"day": 18,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 12:56:04",
"updated_at": "2020-06-22 12:56:04"
},
{
"id": 41,
"base_id": 22,
"day": 28,
"icon": "fe fe-sun text-primary",
"created_at": "2020-06-22 13:16:16",
"updated_at": "2020-06-22 13:16:16"
},
{
"id": 45,
"base_id": 22,
"day": 6,
"icon": "fe fe-alert-circle text-warning",
"created_at": "2020-06-22 13:23:49",
"updated_at": "2020-06-22 13:23:49"
}
]
}
]
}
}
]
}
Ответы (2 шт):
Автор решения: Дядя Вова
→ Ссылка
Добавьте key для циклов v-for.
Из руководства:
Рекомендуем всегда указывать атрибут key с v-for, кроме случаев когда итерируемый контент DOM прост, или вы сознательно используете стратегию обновления по умолчанию для улучшения производительности.
Автор решения: RavenTheX
→ Ссылка
Вам по сути нужно так?
new Vue({
el: "#app",
data: {
test: [{
"id": 1,
"branch_id": 1,
"name": "Большой зал",
"schedule_hall": [{
"id": 1,
"hall_id": 1,
"group_id": 1,
"time": 8,
"day": 1,
"group": {
"id": 1,
"name": "Первая группа",
"programm_id": 1,
"children": [{
"id": 14,
"child_surname": "Владимиров",
"child_name": "Павел",
"group_id": 1,
"journal": [{
"id": 1,
"base_id": 14,
"day": 16,
},
{
"id": 2,
"base_id": 14,
"day": 15,
"icon": "fa fa-times-circle text-alert",
},
{
"id": 132,
"base_id": 14,
"day": 27,
"icon": "fa fa-circle text-warning",
},
{
"id": 133,
"base_id": 14,
"day": 5,
"icon": "fa fa-circle text-warning"
},
{
"id": 135,
"base_id": 14,
"day": 30,
"icon": "fa fa-circle text-warning"
},
{
"id": 136,
"base_id": 14,
"day": 11,
"icon": "fa fa-circle text-warning"
},
{
"id": 147,
"base_id": 14,
"day": 28,
"icon": "fa fa-circle text-warning"
}
]
},
{
"id": 15,
"child_surname": "Иванов",
"child_name": "Сергей",
"group_id": 1,
"journal": [{
"id": 156,
"base_id": 15,
"day": 30,
"icon": "fa fa-circle text-warning"
}]
}
]
}
}]
}],
},
computed: {
computedMans() {
return this.test.schedule_hall[0].group.map(g => {
return g.children.map(item => {
return {
id: item.id,
surname: item.child_surname,
name: item.child_name,
journal: item.journal
}
})
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>