dpst
dpst

Reputation: 1283

How to render list in split groups using Vue.js?

I have a json object returned from the server that has a variable amount of date in roughly this format:

[{"data":{"level":1,"sub_level":1,"value": 10},
 {"data":{"level":1,"sub_level":2,"value": 23},
 {"data":{"level":1,"sub_level":3,"value": 3},
 {"data":{"level":2,"sub_level":1,"value": 55},
 {"data":{"level":2,"sub_level":2,"value": 52}]

I am trying to iterate through the data and get an output similar to the below HTML assuming there were nine elements in the data set to iterate through.

Basically, I want to ouput the dataset into groups of three objects, count the objects in each group and then repeat for the next three.

<div>
  <span>1</span>
  <ul>
    <li>1 item.value</li>
    <li>2 item.value</li>
    <li>3 item.value</li>
  </ul>
</div>
<div>
  <span>2</span>
  <ul>
    <li>1 item.value</li>
    <li>2 item.value</li>
    <li>3 item.value</li>
  </ul>
</div>
<div>
  <span>3</span>
  <ul>
    <li>1 item.value</li>
    <li>2 item.value</li>
    <li>3 item.value</li>
  </ul>
</div>

I'm not sure how the best way to do this in the Vue.js templates.

Upvotes: 6

Views: 7949

Answers (3)

Fernando Retuerta
Fernando Retuerta

Reputation: 1

<div v-for="num in options.length/3" :key="num">
    <span>{{num}}</span>
    <ul class="label" v-for="option in options.slice(num, num+3)" :key="option.value">
        <li>{{option.id}} {{option.value}}</li>
    </ul>
</div>

Upvotes: 0

Carol Skelly
Carol Skelly

Reputation: 362380

I know this answer is late, but I thought it might be helpful to someone. The simplest way I found is using a "chunk" method in the Vue controller. This will split up the array into n groups...

var vm = new Vue({
  el: '#app',
  data: {
    nColumns: 3, // number of groups/columns
    items: [
      {name: 'MacBook Air Pro', price: 1900},
      {name: 'MacBook Pro', price: 1400},
      ...
    ],
    groupedItems: []
  },
  mounted() {
    var _self = this;
    // divide into n groups
    _self.chunk(this.items, Math.ceil(this.items.length/this.nColumns)); 
  },
  methods: {
    chunk: function(arr, size) {
      var newArr = [];
      for (var i=0; i<arr.length; i+=size) {
        newArr.push(arr.slice(i, i+size));
      }
      this.groupedItems  = newArr;
    }
  }
});

Then, in the markup use nested v-for to repeat the groups, and then the items in each group. You can also use :set to maintain a total count of items...

<div class="row">
        <div v-for='(g, groupIndex) in groupedItems'>
            <div v-for='(item, index) in g' :set="ictr=groupIndex*(groupedItems[0].length)+(index+1)">
                {{ictr}} {{ item.name }}
            </div>
        </div>
</div>

Working Demo (uses Bootstrap 4 for responsive layout)

Upvotes: 3

AfikDeri
AfikDeri

Reputation: 2109

You can split the array into chunks and then render each chunk individually.

let arrays = [];
const size = 3;

while (yourArray.length > 0)
    arrays.push(yourArray.splice(0, size));

Then iterate between them like so:

<div v-for="item in arrays[0]">
  <span>1</span>
  <ul>
    <li>1 item.value</li>
    <li>2 item.value</li>
    <li>3 item.value</li>
  </ul>
</div>
<div v-for="item in arrays[1]">
 <span>2</span>
  <ul>
    <li>1 item.value</li>
    <li>2 item.value</li>
    <li>3 item.value</li>
  </ul>
</div>

Or you can go with nested elements without the split:

<div v-for="i in 3">
  <span>{{ i + 1 }}</span>
  <div>
    <ul>
      <li v-for="j in 3">{{ j + 1 }} yourArray[i+j].value</li>
    </ul>
  </div>
</div>

I haven't tested the code but it should work :)

Upvotes: 0

Related Questions