I have offers cards list rendering thru the loop. Every 3rd col (bootstrap) elements i add row div. Now i need to add another col element (banner block) for every 6th element. For render some thing like that:
How i can implement that?
My code now
<div class="row" v-for="i in Math.ceil(offers.length / 3)">
<div class="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12" v-for="offer in offers.slice((i-1)*3, i*3)">
<h2>{{offer.name}}</h2>
<h2>{{offer.desc}}</h2>
</div>
</div>
Advertisement
Answer
I would recommend you do less programming in the view and more in the view model. Create a computed that splits up your data into series of offers and banners, and also into rows, then use that computed in a straightforward way.
const chunk = (arr, size) =>
arr
.reduce((acc, _, i) =>
(i % size) ?
acc :
[...acc, arr.slice(i, i + size)], []);
new Vue({
el: '#app',
data: {
offers: []
},
computed: {
rows() {
const withBanners = chunk(this.offers, 5).map((arr) => [...arr, {name: 'banner', type: 'Banner'}]).reduce((a, b) => a.concat(b), []);
return chunk(withBanners, 3);
}
},
mounted() {
setTimeout(() => {
this.offers = [{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
},
{
name: 'offer'
}
];
}, 500);
}
});#app {
display: grid;
}
.row {
display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(3, auto);
justify-content: left;
}
.box {
width: 8rem;
height: 8rem;
}
.banner {
background-color: #f9c;
}
.offer {
background-color: #99f;
}<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div class="row" v-for="row in rows">
<div class="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12" v-for="item in row">
<div v-if="item.type === 'Banner'" class="banner box">
<h2>{{item.name}}</h2>
</div>
<div v-else class="offer box">
<h2>{{item.name}}</h2>
</div>
</div>
</div>
</div>