Home > Software design >  Way to remove custom component code repetition in Vue?
Way to remove custom component code repetition in Vue?

Time:12-24

My custom component code:

<template>
<div >
    <div >
        {{ title }}
    </div>
    <div >
        {{ date }}
    </div>
    <div >
        {{ time }}
    </div>
    <div >
        {{ address }}
    </div>
    <div >
        Learn more!
    </div>
</div>
<script>
export default {
    name: 'EventCard',
    props: {
        title: { 
            type: String, 
            required: true, 
            default: ''
        }, 
        date: { 
            type: String, 
            required: false, 
            default: ''
        },
        time: { 
            type: String, 
            required: true, 
            default: ''
        },
        address: { 
            type: String, 
            required: true, 
            default: ''
        },
        type: {
            type: String,
            required: true,
            default: ''
        }
    }
}

with some styling as well.

I am then using this custom component in an EventDiscoveryPage.vue file where I have the code written as such:

        <div >
        <EventCard  :title="'food event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'music event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'music event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'comedy event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'music event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'food event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'music event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'comedy event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
        <EventCard  :title="'comedy event'" :date="'date-test'" :time="'time-test'" :address="'address-test'" :type="'music'" />
    </div>

As of right now, the code works as intended, but I am wanting to reduce this seemingly redundant code and was wondering if I am able to use a v-for in some way to automate this process a little bit more, but I wasn't sure because I saw that v-for required preset data? I wasn't able to figure out using the documentation and was wondering if anyone had any recommendations.

CodePudding user response:

You can refactor your code using a v-for iterating over an array of objects like this:

<template>
  <div >
    <EventCard v-for="event in events" :key="event.title" : :title="event.title" :date="event.date" :time="event.time" :address="event.address" :type="event.type" />
  </div>
</template>

<script>
export default {
  data () {
    return {
      events: [
        { class: 'food-event', title: 'food event', date: 'date-test', time: 'time-test', address: 'address-test', type: 'music' },
        { class: '...', title: '...', date: '...', time: '...', address: '...', type: '...' },
        ...
      ]
    }
  }
}
</script>

CodePudding user response:

You can reduce all of it to one object in your EventDiscoveryPage.vue like this and then add the objects to an array and loop over the array:

<script setup>
    // Factory Function to build objects (You can easily add types as well)
    function createCard( class, title, date, time, address, type ) {
        return {
            class,
            title,
            date,
            time,
            address,
            type
        }
     }

    const food = createCard('food-event', 'food event', 'date-test', 'time-test', 'address-test', 'music')
    const otherEvent = createCard( class, title, date, time, address, type )

    // Add each event to the cards array
    let cards = [food, otherEvent]
</script>


<div >
    <EventCard v-for="card in cards" : :data="card" />
</div>
  • Related