С помощью setTimeout добавлять класс
Необходимо добавлять класс, по очереди, блокам которые находятся в v-for, каждые n-секунд и удалять предыдущим. Чтобы, к примеру, каждую секунду появляся новый блок, а старый удалялся и так зациклить.
<div v-for="(block, index) in blocks" :key="index" class="blockItem">{{block.title}}</div>
data: () => ({
blocks: [
{
title: 'Раз',
},
{
title: 'Два',
},
{
title: 'Три',
},
],
}),
Как это реализовать?
Ответы (1 шт):
Чтобы оперировать данными из массива, необходимо полагаться, что каждый элемент имеет уникальный идентификатор.
Создаем в data переменную - idActiveBlock, в которой будем хранить индекс активного элемента из массива blocks (того, элемента, которому нужно присвоить класс css - active). В template добавляем соответствующие выражения, которые будут формировать классы для элементов из массива, полагаясь на данные:
<div v-for="block in blocks" :key="block.id" :class="['blockItem', {active: block.id === idActiveBlock}]">
{{block.title}}
</div>
Создаем функцию, которая будет отвечать за изменение индекса активного элемента, в которой после манипуляций с индексом, формируем отложенный запуск этой же функции еще раз, через заданный промежуток времени.
Для управления отображением можно использовать css стили.
Для наглядности пример:
new Vue({
el: '#app',
data: () => ({
run: false,
timer: null,
idActiveBlock: 0,
blocks: [{
id: 1,
title: 'Раз',
},
{
id: 2,
title: 'Два',
},
{
id: 3,
title: 'Три',
},
],
}),
methods: {
toggleStart() {
this.run = !this.run
if (this.run) {
this.editParamsActiveBloks()
} else {
clearTimeout(this.timer)
}
},
editParamsActiveBloks() {
this.idActiveBlock = this.idActiveBlock < this.blocks.length ? this.idActiveBlock + 1 : 1
const idNextActiveElement = this.blocks[this.idActiveBlock - 1].id || 0
if (this.run) {
this.timer = setTimeout(this.editParamsActiveBloks, 1000);
}
},
},
})
.flex {
display: flex;
}
.blockItem {
padding: 20px;
opacity: .2;
background: #eee;
}
.active {
background: #42b883;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
Индекс активного блока = {{idActiveBlock}}
<div class="flex">
<div v-for="block in blocks" :key="block.id" :class="['blockItem', {active: block.id === idActiveBlock}]">
{{block.title}}
</div>
</div>
<button @click="toggleStart">
<template v-if="run">Стоп</template>
<template v-else>Старт</template>
</button>
</div>