Vue JS – Looping through components

I’m currently refactoring my code to make it look cleaner and I stumbled upon a section which doesn’t really seem neat and may not be the best practise to execute this type of code.

Statistics.vue – In here I’m using a StatisticsCard component 3 times in order to display each of the relevant data for each component

<template>
  <div class="statistics-section">
    <img class="statistics-image" src="@/assets/img/images/img_stats@2x.png" alt="">
    <h3 class="section-title">Statistieken</h3>
    <p class="section-description">De studenten van Het Creiler hebben samen ...</p>
    <div class="statistics-cards">
      <StatisticsCard :imageUrl="require('@/assets/img/images/img_stats_km@2x.png')"
                      :title="'kilometers'"
                      :number="kilometers"
                      :type="'GELOPEN'"/>

      <StatisticsCard :imageUrl="require('@/assets/img/images/img_stats_collected@2x.png')"
                      :title="'stukken'"
                      :number="trashCollected"
                      :type="'AFVAL OPGRUIMD'"/>

      <StatisticsCard :imageUrl="require('@/assets/img/images/img_stats_photos@2x.png')"
                      :title="'foto\'s'"
                      :number="photosTaken"
                      :type="'GEDEELD'"/>
    </div>
  </div>
</template>

<script>
  import StatisticsCard from '@/components/partials/onepager/StatisticsCard';

  export default {
    name: 'Statisticts',
    components: {StatisticsCard},
    props: {
      kilometers: {
        type: Number,
        required: true
      },
      trashCollected: {
        type: Number,
        required: true
      },
      photosTaken: {
        type: Number,
        required: true
      },
    },
  }

School.vue – This is the main component and here I make all the relevant api calls. Statistics.vue is rendered to show all the information from the api.

<div class="section-grid">
    <Statistics :kilometers="schoolOnepager.statistics.collectedTrashCount"
                :trash-collected="schoolOnepager.statistics.schoolSharedPhotosTrashCount"
                :photos-taken="schoolOnepager.statistics.schoolTotalDistanceWalked"/>
</div>

...

computed: {
    schoolOnepager: function () {
      return this.$store.getters.getSchoolOnepager;
    },
}

Is there any better way I can do this instead of defining the statistics card component 3 times, can I perhaps loop through and let each one of them show the specific information.

7 thoughts on “Vue JS – Looping through components”

  1. You could create an array of statistics objects, and loop them.

    for example:
    statistics: [ { title: "kilometers", number: 'kilometers', type: 'GELOPEN' }, { title: "kilometers", number: 'kilometers', type: 'GELOPEN' } ]

    and then refactor your template components:

          <div v-for="(statistic, i) in statistics">
    <StatisticsCard :imageUrl="require('@/assets/img/images/img_stats_km@2x.png')"
                      :title="statistic.title"
                      :number="statistic.number"
                      :type="statistic.type"/>
    </div>
    
    Reply
  2. You can directly use v-for on a custom component, like any normal element:

    <StatisticsCard v-for="(item, index) in items" :key="index"
     :title="'kilometers'"
     :number="item.kilometers"
     :type="item.type"
    ></StatisticsCard>
    

    provided your items array should be like

    [
     {
       title: 'kilometers',
       type: 'stunk'
    },
    {
       title: 'hgdfb',
       type: 'dvnvffv'
    },
    ......
    ]
    
    Reply

Leave a Comment