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>