6

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.

3 Answers 3

3

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Nice solution! It might be easier to user the chunk method in a computed property. Then it will be updated anytime new values are added to items.
0

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 :)

Comments

0

<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>

1 Comment

An answer should be accompanied by an explanation of the relevant parts of the solution, to help people interested in it but with less understanding

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.