Pasan Kamburugamuwa
Pasan Kamburugamuwa

Reputation: 89

Dynamic list rendering in VueJS

I am trying to display the images and its content in a web page (VueJS). I am having a problem with display them in a row with maximum number of elements for each row is 4.

<div className="container" style="padding-top: 1rem; width: 100%; min-height: 600px">
  <div class="columns">
    <div class="column">
      <div class="card" style="width: 15rem; height: 15rem; margin: 20px" v-for="(image, index) in allImagesData"
           :key="index">
        <img class="card-img-top" :src='image.media_url' alt="Image" style="max-height: 12rem; max-width: 10rem;">
        <p>{{ image.platform }}</p>
        <p>{{ image.count }}</p>
      </div>
    </div>
  </div>
</div>  

The images shows in a vertically, I need to have it in horizontally.

enter image description here

Can anyone help me with this to display the images in horizontally. The list will have different number of elements each time.

Upvotes: 1

Views: 203

Answers (2)

kissu
kissu

Reputation: 46602

This should work fine

<template>
  <div class="columns">
    <div v-for="image in allImagesData" :key="image.platform" class="column">
      <img class="fitting-image" :src="image.media_url" />
      <p>{{ image.platform }}</p>
      <p>{{ image.count }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      allImagesData: [
        {
          platform: 'facebook',
          media_url: 'https://source.unsplash.com/random/200x200?sig=1',
          count: 12,
        },
        {
          platform: 'twitter',
          media_url: 'https://source.unsplash.com/random/200x200?sig=2',
          count: 15,
        },
        {
          platform: 'instagram',
          media_url: 'https://source.unsplash.com/random/200x200?sig=3',
          count: 4,
        },
        {
          platform: 'mastodon',
          media_url: 'https://source.unsplash.com/random/200x200?sig=4',
          count: 664,
        },
        {
          platform: 'discord',
          media_url: 'https://source.unsplash.com/random/200x200?sig=5',
          count: 15,
        },
        {
          platform: 'discord2',
          media_url: 'https://source.unsplash.com/random/200x200?sig=6',
          count: 15,
        },
        {
          platform: 'discord3',
          media_url: 'https://source.unsplash.com/random/200x200?sig=7',
          count: 15,
        },
        {
          platform: 'discord4',
          media_url: 'https://source.unsplash.com/random/200x200?sig=8',
          count: 15,
        },
        {
          platform: 'discord5',
          media_url: 'https://source.unsplash.com/random/200x200?sig=9',
          count: 15,
        },
        {
          platform: 'discord6',
          media_url: 'https://source.unsplash.com/random/200x200?sig=10',
          count: 15,
        },
      ],
    }
  },
}
</script>

<style scoped>
.columns {
  display: grid;
  --gap: 1rem; /* update this variable to create more/less distance with elements */
  grid-template-columns: repeat(auto-fit, minmax(auto, calc(25% - var(--gap))));
  gap: var(--gap);
}
.column {
  background: paleturquoise;
  border: 3px solid tomato;
}
.fitting-image {
  object-fit: cover;
  height: auto;
  width: 100%;
}
</style>

Looks like this (with the devtools grid layout overlay)

enter image description here

Stays at 25% on all screen sizes and is easy to toggle the gap in between each elements.

Upvotes: 1

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23480

Try to set flex on column:

const app = Vue.createApp({
  data() {
    return {
      allImagesData: [{platform: 1, count:1, media_url: 'https://picsum.photos/200'}, {platform: 5, count:5, media_url: 'https://picsum.photos/200'}, {platform: 2, count:2, media_url: 'https://picsum.photos/200'}, {platform: 3, count:3, media_url: 'https://picsum.photos/200'}, {platform: 4, count:4, media_url: 'https://picsum.photos/200'}],
    };
  },
})
app.mount('#demo')
.column {
  display: flex;
  flex-wrap: wrap;
}
.card {
  flex: 1 0 21%;
  border: 1px solid grey;
  border-radius: 5px;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <div className="container" style="padding-top: 1rem; width: 100%; min-height: 600px">
    <div class="columns">
      <div class="column">
        <div class="card" style="max-width: 15em; height: 15em; margin: 20px" v-for="(image, index) in allImagesData"
             :key="index">
          <img class="card-img-top" :src='image.media_url' alt="Image" style="max-height: 12rem; max-width: 10rem; border-top-left-radius: 5px; border-top-right-radius: 5px;">
          <p>{{ image.platform }}</p>
          <p>{{ image.count }}</p>
        </div>
      </div>
    </div>
  </div>  
</div>

Upvotes: 1

Related Questions