Generate line break in VueJS with v-if

I have a method that does a search in an API made in laravel and returns me a json, I need to go through this json in a v-for and every 3 interactions a new row is created. In PHP it would be more or less like this.

foreach ($variable as $key => $value) {
        if($i == 3){
            echo "</div>"; //fecha a div de classe row
            echo '<div class="row">'; //Abre a div de classe row
        }
    }

If anyone can give me a light thank you.

<template>
<div class="row">
    <div class="card bg-primary-gradient collapsed-card" v-for="(item, index) in items" :key="index.id">
          <div class="card-header">
            <h3 class="card-title">{{item.title}}</h3>

            <div class="card-tools">
              <button type="button" class="btn btn-tool" data-widget="collapse"><i class="fa fa-minus"></i>
              </button>
            </div>
            <!-- /.card-tools -->
          </div>
          <!-- /.card-header -->
          <div class="card-body" style="display: none;">
            {{item.price}}
          </div>
          <!-- /.card-body -->
    </div>
</div>

Author: PaulinhoCaP, 2019-01-11

2 answers

const app = new Vue({
  el:"#app",
  data:{
    items: [
      'feijão',
      'arroz',
      'macarrão',
      'carne',
      'tomate',
      'pimentão',
      'farofa',
      'cuscuz',
    ]
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div v-for="(item, i) in items" :key="i">
     {{item}}
    <!--Executa o módulo do índice com o 3. Sempre que a divisão do índice por 3 tiver um resto igual a 2, o if é verdadeiro-->
    <div v-if="i%3===2">nova linha a cada 3</div>
  </div>
</div>
 0
Author: klawdyo, 2019-02-09 19:45:32

I see two practical solutions to your problem:

1. Median solution

Create a computed property that provides an array of arrays, where each "child" array has 3 elements only. Ex.:

new Vue({
  el: "#app",
  data: {
    items: [
      {nome: "Item 1", preco: 10},
      {nome: "Item 2", preco: 20},
      {nome: "Item 3", preco: 30},
      {nome: "Item 4", preco: 40},
      {nome: "Item 5", preco: 50},
      {nome: "Item 6", preco: 60},
      {nome: "Item 7", preco: 70},
      {nome: "Item 8", preco: 80},
    ]
  },
  computed: {
    chunks() {
      let result = []
      for (let i=0, l=this.items.length; i<l ; i+=3) {
        let chunk = []
        this.items[i] && chunk.push(this.items[i])
        this.items[i+1] && chunk.push(this.items[i+1])
        this.items[i+2] && chunk.push(this.items[i+2])
        result.push(chunk)
      }
      return result
    }
  }
  
})
.item {
  display: inline-block;
  width: 150px;
  border: 1px solid #babaca;
  margin: 3px;
  padding: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">
  <div v-for="(chunk, i) in chunks" :key="i" class="container">
    <div v-for="(item, j) in chunk" :key="j" class="item">
      {{ item.nome }} ({{ item.preco }})
    </div>
  </div>
</div>

2. Better solution

Use CSS to customize the presentation of your data. You can use Flexbox or use the grid system of the CSS framework you are already using. Example using Bootstrap 4 Grid :

new Vue({
  el: "#app",
  data: {
    items: [
      {nome: "Item 1", preco: 10},
      {nome: "Item 2", preco: 20},
      {nome: "Item 3", preco: 30},
      {nome: "Item 4", preco: 40},
      {nome: "Item 5", preco: 50},
      {nome: "Item 6", preco: 60},
      {nome: "Item 7", preco: 70},
      {nome: "Item 8", preco: 80},
    ]
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">


<div id="app" class="container-fluid">
  <div class="row">
    <div class="col-4" v-for="(item, i) in items" :key="i">
      <div class="card">
        <div class="card-body">
          <div class="card-title">{{ item.nome }}</div>
          <div class="card-text">{{ item.preco }}</div>
        </div>
      </div>
    </div>
  </div>
</div>
 3
Author: fernandosavio, 2019-01-11 18:28:07