Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vuejs v-for add bootstrap row every 5 items

I have an array of items like 'Item 1', 'Item 2' up to 'Item 25'. I want the HTML after rendering look like this:

<div class="row">
   <div>Item 1</div>
   <div>Item 2</div>
   <div>Item 3</div>
   <div>Item 4</div>
   <div>Item 5</div>
</div>
<div class="row">
   <div>Item 6</div>
   <div>Item 7</div>
   <div>Item 8</div>
   <div>Item 9</div>
   <div>Item 10</div>
</div>

What is the proper way to express this in vue.js?

 <div class="row">
    <span  v-for="(item, index) in items">
         // do something like this in vue.js style: 
         // if (item % 5 == 0) print "</div><div class='row'>"
         <app-field >{{ item }}</app-field>
    </span>
</div>
like image 933
herrjeh42 Avatar asked Jan 29 '17 18:01

herrjeh42


3 Answers

You can try this:

  <div class="row" v-for="i in Math.ceil(items.length / 5)">
    <span v-for="item in items.slice((i - 1) * 5, i * 5)">
      {{item}}
    </span>
  </div>

See a working example:

new Vue({
  el: '#demo',
  data: {
    items: [
      'item 1',
      'item 2',
      'item 3',
      'item 4',
      'item 5',
      'item 6',
      'item 7',
      'item 8',
      'item 9',
      'item 10',
      'item 11',
      'item 12',
      'item 13',
      'item 14',
      'item 15',
      'item 16',
      'item 17',
      'item 18',
      'item 19',
      'item 20',
      'item 21',
      'item 22',
      'item 23',
      'item 24',
      'item 25'
    ]
  }
})
.row {
  border: solid 1px #404040;
  padding: 10px;
}
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="demo">
  <div class="row" v-for="i in Math.ceil(items.length / 5)">
    <span v-for="item in items.slice((i - 1) * 5, i * 5)">
  {{item}}
</span>
  </div>
</div>
like image 199
CD.. Avatar answered Nov 19 '22 22:11

CD..


In addition to the example above which I think is fine, I would define the calculations as computed properties and methods for more readable code. See the JSFiddle:

 computed:{
    rowCount() {     
       return Math.ceil(this.items.length / this.itemsPerRow);
    }
 },
like image 30
Cristi Jora Avatar answered Nov 19 '22 20:11

Cristi Jora


Or you can do the same using lodash _.chunk(), which personally I find more readable.

Template:

<div class="columns" v-for="chunk in productChunks">

    <div class="column is-one-quarter" v-for="product in chunk">
       // stuff
    </div>

</div>

Then

    computed: {
      productChunks(){
          return _.chunk(Object.values(this.products), 4);
      }
    },

Personally I import lodash globally as I use it so often, in main.js:

import _ from 'lodash'

Remember to 'npm install --save lodash'

like image 20
Joel Avatar answered Nov 19 '22 21:11

Joel