skip to Main Content

Good afternoon.

I am currently working with the following VueJS component:

<template>
   <div>
     <table>
       <tbody>
         <tr v-for="(item, index) in items" :key="index">
           <td>{{ item.id }}</td>
           <td>{{ item.name }}</td>
          <td>{{ item.price }}</td>
         </tr>
       </tbody>
     </table>
   </div>
 </template>
 
 <script>
 export default {
 data() {
 return {
 items: [
 id: 1, name: "Item 1", price: 10.99 },
 id: 2, name: "Item 2", price: 20.50 },
 id: 3, name: "Item 3", price: 15.75 },
 id: 4, name: "Item 4", price: 15.75 }

      ]
     };
   }
 };
 </script>

I would like to modify the behavior of said table. I am trying to force that the table has a total of 3 columns. The table cells should be filled from left to right and from top to bottom (always ensuring that there are 3 columns).

For example, considering the variable "items" defined above, the table should look as shown below:

--------------------------------
| Item 1 | Item 2 | Item 3 |
| Item 4 |
----------------------------

I tried to use "v-if" and "v-for" directives to accomplish this, but I can’t quite understand how to make this "reactive" (independent of the number of elements of the list). I find it a bit confusing to force only 3 elements per row.

How could I accomplish this?

Thank you very much for your attention.

Best regards.

The expected result should be a table like the one provided above.

2

Answers


  1. As mentioned in my comment, don’t use a table as you no longer have tabular data.

    Use CSS grid and style for as many columns as you want. You can even use CSS Media Queries to adjust columns based on device width, which is much easier to do with grid that it is with columns.

    Here’s a quick functional demo

    Code :

    <script setup>
    import { ref } from 'vue'
    
    const msg = ref('Hello World!')
    const items = [
     {id: 1, name: "Item 1", price: 10.99 },
     {id: 2, name: "Item 2", price: 20.50 },
     {id: 3, name: "Item 3", price: 15.75 },
     {id: 4, name: "Item 4", price: 15.75 }]
    </script>
    
    <template>
    
     <div>
         <ul id="items">
             <li v-for="(item, index) in items" :key="index">
              <span class="id">Id: {{ item.id }}</span>
              <h2 class="name">{{ item.name }}</h2>
              <span class="price">{{ item.price }}</span>
             </li>
         </ul>
       </div>
    
    </template>
    <style>
      #items{
        list-style: none; 
        padding: 0;
        /* Make a grid */
        display: grid;
        /*Make it 3 columns */
        grid-template-columns: 1fr 1fr 1fr;
        grid-gap: 1em;
      }
    
      #items li {border: 1px solid black ;
      padding: 3px;
      }
      
      #items li .name{  
        text-align: center
      }
    
      #items li .price:before{  
        content: "$";
        display:inline-block;
    }
    
    </style>
    
    Login or Signup to reply.
  2. This can be solved with HTML.
    On the td element there a two attributes colspan and rowspan. These allow you to control whether a cell spans some columns or rows.
    To achieve you desired result you have to wrap the tr with a template and move the v-for attribute to this template. Then add after the first tr, but still inside the template, add a new tr. Inside the tr add two td elements. Into the first goes your Item 4. The second one can be left empty, but it must have the attribute colspan="2"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search