2

I have a list of cars as below:

<script>

const sampleCars = [
  {
    id: 1,
    name: 'Cressida',
    model: 'XXC',
    manufacturer: 'Toyota',
    price: '$10,000',
    inEditMode: false 
  },
  {
    id: 2,
    name: 'Corolla',
    model: 'ZD-2',
    manufacturer: 'Toyota',
    price: '$12,000',
    inEditMode: false 
  },
  {
    id: 3,
    name: 'Condor',
    model: '27-9',
    manufacturer: 'Mazda',
    price: '$8,000',
    inEditMode: false 
  }
]

export default {
  data() {
    return {
      cars: sampleCars
    }
  }
}


</script>

<style>
.grid {
  display: grid;
  grid-template-columns: repeat(5, auto);
  gap: 10px;
}

</style>

I want to display the items in a css grid with 5 columns.

If I use vue code like below:

<template>
  <div >
    <div class="grid">
      <div>Name</div>
      <div>Model</div>
      <div>Manufacturer</div>
      <div>Price</div>
      <div>buttons</div>      
    </div>
    <div v-for="car in cars" :key="car.id" class="grid">
      <div>{{car.name}}</div>  // "child div"
      <div>{{car.model}}</div>
      <div>{{car.manufacturer}}</div>
      <div>{{car.price}}</div>
      <div>buttons</div>
    </div>
  </div>
</template>

The problem with this code is that each item is displayed in its own grid. (And therefore not aligned as in image below). Using v-for all car properties become a child of the root div. So essentially I want all "child divs" to be a root of one CSS grid div. How can I achieve that?

enter image description here

With VueJS 2

Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
RaelB
  • 3,301
  • 5
  • 35
  • 55
  • well, you assigning the grid class for each row, so each row is its own grid. there are plenty of resources of how you can create a table with css grid, you should take a look at some. – Ezycod Oct 23 '20 at 09:55

2 Answers2

2

Make the table header in one grid and table rows in another grid :

Vue.config.devtools = false;
Vue.config.productionTip = false;
const sampleCars = [{
    id: 1,
    name: 'Cressida',
    model: 'XXC',
    manufacturer: 'Toyota',
    price: '$10,000',
    inEditMode: false
  },
  {
    id: 2,
    name: 'Corolla',
    model: 'ZD-2',
    manufacturer: 'Toyota',
    price: '$12,000',
    inEditMode: false
  },
  {
    id: 3,
    name: 'Condor',
    model: '27-9',
    manufacturer: 'Mazda',
    price: '$8,000',
    inEditMode: false
  }
]

new Vue({
  el: '#app',

  data() {
    return {
      cars: sampleCars
    }
  }
})
.grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(92px,1fr));
  gap: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


<div id="app" class="container">

  <div>
    <div class="grid">
      <div>Name</div>
      <div>Model</div>
      <div>Manufacturer</div>
      <div>Price</div>
      <div>buttons</div>
    </div>
    <div v-for="car in cars" :key="car.id">
      <div class="grid">
        <div>{{car.name}}</div>
        <div>{{car.model}}</div>
        <div>{{car.manufacturer}}</div>
        <div>{{car.price}}</div>
        <div>buttons</div>
      </div>
    </div>
  </div>
</div>
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
  • Yeah, that's what I am looking for, *but* that does not work for me. In the compile error message it says that "Elements in iteration expect to have 'v-bind:key'". But also, I cannot use :key with template element "' – RaelB Oct 23 '20 at 10:25
2

The best solution I found was to use Vue-Fragment from https://github.com/Thunberg087/vue-fragment

The child elements in the v-for loop will end up being at the root level:

<template>
  <div >
    <div class="grid">
      <div>Name</div>
      <div>Model</div>
      <div>Manufacturer</div>
      <div>Price</div>
      <div>buttons</div>  

      <fragment v-for="car in cars" :key="car.id"  >
        <div>{{car.name}}</div>
        <div>{{car.model}}</div>
        <div>{{car.manufacturer}}</div>
        <div>{{car.price}}</div>
        <div>buttons</div>
      </fragment>     
    </div>   

  </div>
</template>

See also this SO question: Is there something like React.Fragment in Vue?

RaelB
  • 3,301
  • 5
  • 35
  • 55