looping in Vue.JS to iterate over some a group of items and wrapping them in an element

时间:2018-02-03 09:11:30

标签: javascript vue.js v-for

I am new in Vue, I want to create a Loop (v-for) for creating something like this block

<div class="The-row">
 <span> {{ * }} </span>
 <span> {{ * }} </span>
</div>

in this block each 2 span wrap with a Tag with " The-row " class and each SPAN tag has an instead item , that means :

<div class="The-row">
 <span> {{ item[0] }} </span>
 <span> {{ item[1] }} </span>
</div>
----------------------------------
<div class="The-row">
 <span> {{ item[2] }} </span>
 <span> {{ item[3] }} </span>
</div>

what am i doing for create loop , i know this way for show an element in every twice loop with use

<div v-if=" index % 2 == 0 " >

see this pen -> https://codepen.io/hamidrezanikoonia/pen/RQrvKJ

in this pen , i have 2 important proble 1. the first item dosent show 2. the items cant be even

and , please check im in correct way or i can use another way

thanks

3 个答案:

答案 0 :(得分:1)

I would probably try grouping the data (using a computed property), rather than make the template more complicated.

However, the shortest fix is to swap your indexes, since $index === 0 is hidden and $index === 1 is shown, etc.

<input class="option-input"...
<label class="option" for="option-1">
  <span class="option__label">
    <sub>{{items[$index -1].name}}</sub> 
  </span>
</label>

<input class="option-input"...
<label class="option" for="option-1">
  <span class="option__label">
    <sub>{{items[$index].name}}</sub> 
  </span>
</label>

Here is a shorter version of the grouping function.

Ref: Array.prototype.reduce()

console.clear()
const items = [
  { id: 1 , name: 'one'},
  { id: 2 , name: 'two'},
  { id: 3 , name: 'three'},
  { id: 4 , name: 'four'},
  { id: 5 , name: 'five'},
  { id: 6 , name: 'six'},
  { id: 7 , name: 'seven'},
  { id: 8 , name: 'eight'},
  { id: 9 , name: 'nine'},
  { id: 10 , name: 'ten'}
];

const grouped = items.reduce((acc, item, index, items) => {
  return index % 2 === 0 ? acc : [...acc, [items[index -1], item]];
}, [])

console.log(grouped);
.as-console-wrapper { min-height: 100% !important; top: 0 }

答案 1 :(得分:1)

I also would prefer changing the structure of the data rather then building a complicated template. But it would work like this:

<div class="option-row" v-if="($index + 1) % 2 == 1 ">

  <input class="option-input" id="option-1" type="radio" name="options" />
  <label class="option" for="option-1">
    <span class="option__label">
      <sub>{{item.name}}</sub>
    </span>
  </label>

  <input v-if="items[$index + 1]" class="option-input" id="option-1" type="radio" name="options" />
  <label v-if="items[$index + 1]" class="option" for="option-1">
    <span class="option__label">
      <sub>{{items[($index + 1)].name}}</sub>
    </span>
  </label>

</div>

This is the same solution Richard Matsen already mentioned. Only with a little enhancement: avoid errors if the odd element doesn't exist.

You can use a computed property for this:

computed: {
    groupedItems() {
        let grouped = [];
        index = -1;
        for (let i = 0; i < this.items.length; i++) {
            if (i % 2 == 0) { 
                index++;
                grouped[index] = [];
            }
            grouped[index].push(this.items[i]);
        }
        return grouped;
    }
}

And your Template would get cleaner:

<template v-for="items in groupedItems">
    <div class="option-row">
        <div v-for="item in items">
            <input class="option-input" id="option-1" type="radio" name="options" />
            <label class="option" for="option-1">
                <span class="option__label">
                    <sub>{{item.name}}</sub>
                </span>
            </label>
        </div>  
    </div>
</template>

答案 2 :(得分:1)

你可以这样工作

computed: {
groupedItems() {
    let grouped = [];
    index = -1;
    for (let i = 0; i < this.items.length; i++) {
        if (i % 2 == 0) { 
            index++;
            grouped[index] = [];
        }
        grouped[index].push(this.items[i]);
    }
    return grouped;
}
 }