thelandog
thelandog

Reputation: 734

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/[email protected]" 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/[email protected]')"
                      :title="'kilometers'"
                      :number="kilometers"
                      :type="'GELOPEN'"/>

      <StatisticsCard :imageUrl="require('@/assets/img/images/[email protected]')"
                      :title="'stukken'"
                      :number="trashCollected"
                      :type="'AFVAL OPGRUIMD'"/>

      <StatisticsCard :imageUrl="require('@/assets/img/images/[email protected]')"
                      :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.

Upvotes: 0

Views: 86

Answers (2)

jcmortensen
jcmortensen

Reputation: 111

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

for example in VueX Store:

statistics: [
 {
   title: 'kilometers',
   number: 12,
   type: 'GELOPEN'
 },
 {
   title: 'kilometers',
   number: 5,
   type: 'GELOPEN'
 }
]

*The data is requested from School.vue and from here the data in the store is mutated. In Statistics.vue the data is a computed property called schoolOnepager that import the statistics data from the VueX store

and then refactor your template components:

<StatisticsCard v-for="(statistic, i) in statistics" key="i" :imageUrl="require('@/assets/img/images/[email protected]')"
                  :title="statistic.title"
                  :number="statistic.number"
                  :type="statistic.type"/>

Upvotes: 2

Amaarockz
Amaarockz

Reputation: 4684

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'
},
......
]

Upvotes: 1

Related Questions