Skip to content
Advertisement

vue.js insert block for every 6th loop element

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:

enter image description here

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>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement