Home > database >  Group visually data as columns while HTML0. rendered as row
Group visually data as columns while HTML0. rendered as row

Time:02-21

In a VueJS component, I want to render the data which I receive from an API structured as shown below (array of objects).

const data = [
  {
    "firstName": "Nick",
    "lastName": "Pappas",
    "photo": "https://via.placeholder.com/150",
  },
  {
    "firstName": "John",
    "lastName": "Stamos",
    "photo": "https://via.placeholder.com/150",
  },
  {
    "firstName": "George",
    "lastName": "Papadopoulos",
    "photo": "https://via.placeholder.com/150",
  }
]

My goal is to produce a "table-looking" layout with the significant requirement: every object isn't a row, it's a column.

  <script src="https://cdn.tailwindcss.com"></script>

<div >
  <div >
    <div >
      photo1
    </div>
    <div >
      photo2
    </div>
    <div >
      photo3
    </div>
  </div>
  <div >
    <div >
      George
    </div>
    <div >
      Nick
    </div>
    <div >
      John
    </div>
  </div>
</table>

How could one generate something similar to the above while using the Vue template directives? My hints are:

  • Normalize the data? Create separate arrays for each property of all X persons?
const groupedByKey = {
    "firstNames": ["Nick", "John", "George"],
    "lastNames": ["Pappas", "Stamos", "Papadopoulos"]
    "photos": ["...."]
}
  • visually form columns is by using flex-direction: column on each company container. (The problem with this is it lacks all table properties with regards to element autosizing depending on the content of other elements of the row.)

This of course could be achieved by having one separate loop for each property, but for performance and maintenance reasons this is something that I wish to avoid.

I will upvote and accept answers that provide lodash methods to group the data per key as shown in the snipped but ideally if a CSS/HTML only way (of course using the Vue template directives as much as possible) is possible, it would be preferred.

CodePudding user response:

Merge all objects to a single object by spreading the array into _.mergeWith(), and concatenating the values using the customizer function:

const groupByKey = arr => _.mergeWith({}, ...arr, (
  a = [], b = []) => a.concat(b)
)

const data = [{"firstName":"Nick","lastName":"Pappas","photo":"https://via.placeholder.com/150"},{"firstName":"John","lastName":"Stamos","photo":"https://via.placeholder.com/150"},{"firstName":"George","lastName":"Papadopoulos","photo":"https://via.placeholder.com/150"}]

const result = groupByKey(data)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

CodePudding user response:

Flexbox is a viable solution here, despite your concern about auto-sizing issues. (Feel free to point out those issues in my demo below)

You could render the list of data with v-for, where each iteration is a column:

<template>
  <div >
    <div  v-for="col in data">
      <img  :src="col.photo" :alt="col.firstName">
      <div >{{ col.firstName }}</div>
    </div>
  </div>
</template>

Then use Flexbox to style .user-table and .user-column:

.user-table {
  display: flex;
  justify-content: space-around;
}
.user-column {
  display: flex;
  flex-direction: column;
}

demo

  • Related