2

How do I make my vue.js component more general and reusable and can pass only the neccessary data?

this is what I want to build:

enter image description here

Structure:

  • the component has a header
  • the component has different inputs
  • the component has a submit button
  • the component has a list as a footer - that is passed depending on the input

My Approach

the parent

// App.vue
<template>
  <div>
    <!-- Component A -->
    <SettingsCard
     :listA="listA"
     cardType="CompA"
    >
     <template v-slot:header>
       Foo - Component A
     </template>
    </SettingsCard>

    <!-- Component B -->
    <SettingsCard
     :listB="listB"
     cardType="CompB"
    >
     <template v-slot:header>
       Bar - Component B
     </template>
    </SettingsCard>
  </div>
</template>

the child:

// SettingsCard.vue
<template>
  <div>
    <slot name="header"></slot>

    <div v-if="cardType === 'CompA'">
     <!-- Show input and submit button for component a -->
    </div>

    <div v-if="cardType === 'CompB'">
     <!-- Show input and submit button for component b -->
    </div>

    <ListComponent
     :cardType="cardType"
     :list="computedList"
    />
  </div>
</template>

<script>
export default {
  props: {
    cardType: String, // for the v-if conditions
    listA: Array,
    ListB: Array
  },
  data() {
   return {
      namefromCompA: '', // input from component A
      namefromCompB: ''  // input from component B
    }
  },
  computed: {
    computedList() {
      // returns an array and pass as prop the the card footer
    }
  }
}
</script>

The problems

  1. I have undefined props and unused data in my SettingsCard.vue component
// CompA:
props: {
 cardType: 'compA',
 listA: [1, 2, 3], // comes from the parent
 listB: undefined // how to prevent the undefined?
}
// CompA:
data() {
  return {
    namefromCompA: 'hello world',
    namefromCompB: '' // unused - please remove me
  }
}
  1. to use v-if="cardType === 'compA'" feels wrong

Do you have a better approach in mind to make this component reusable and remove anything unnecessary?

wittgenstein
  • 3,670
  • 7
  • 24
  • 41

1 Answers1

2

use a method instead of "cardType === 'CompA'".

just try this in your SettingsCard.vue

methods: {
    showMeWhen(type) {
      return this.cardType === type;
    },
  },
}

and your v-if render condition would be like: v-if="showMeWhen('compA')"


update

for exmaple in your namefromCompA/B you can just pass a new prop to display the correct name.

props: {
    cardType: String, // for the v-if conditions
    listA: Array,
    ListB: Array,
    namefromComponent: {
        type: String,
        default: 'NoName'
    }
  },

then in your usage you just pass it like you do with the other props.

<SettingsCard
     :listB="listB"
     cardType="CompB"
     namefrom-component="my Name for component B"
    >
Deniz
  • 1,435
  • 14
  • 29
  • thank you - do you also have a suggestion how I remove the unused properties and data? – wittgenstein Apr 08 '21 at 12:32
  • @wittgenstein i don't understand what you mean. why not simple delete unused stuff and for your `undefined` set a default https://vuejs.org/v2/guide/components-props.html – Deniz Apr 08 '21 at 12:39
  • `Why not just delete unused stuff"` - that's what I'm looking for. How can I delete unused reactive data variables? I think I need to restructure my component architecture. – wittgenstein Apr 08 '21 at 12:49
  • As a addition: There must be a way to avoid creating the instances in the first place. This will spare you from deleting afterwards... – wittgenstein Apr 08 '21 at 12:58