Wat zijn Props?

Props (properties) zijn data die je doorgeeft van een parent component naar een child component. Hiermee maak je componenten herbruikbaar!

Denk aan functies:

Props zijn net als parameters bij functies. Je geeft data mee en het component gebruikt die data.

Een component zonder props is statisch — het toont altijd hetzelfde. Met props wordt het dynamisch!

Props Gebruiken

Stap 1: Definieer de prop in het child component

In Vue 3 met <script setup> gebruik je de defineProps() macro. Je hoeft deze niet te importeren — Vue maakt hem automatisch beschikbaar.

<!-- src/components/Car.vue -->
<script setup>
const props = defineProps(['brand'])
</script>

<template>
  <h1>Hi, I am a {{ brand }}!</h1>
</template>

Goed om te weten: In de template kun je de prop gewoon bij naam gebruiken ({{ brand }}), zonder props.brand.

Stap 2: Geef de prop mee vanuit de parent

<!-- src/App.vue -->
<script setup>
import Car from './components/Car.vue'
</script>

<template>
  <div>
    <Car brand="Ford" />
  </div>
</template>

Resultaat: Hi, I am a Ford!

Meerdere Props

Je kunt meerdere props meegeven door ze in het array (of beter: object — zie verder) te zetten:

<!-- src/components/Car.vue -->
<script setup>
defineProps(['brand', 'color', 'year'])
</script>

<template>
  <div>
    <h1>Hi, I am a {{ brand }}!</h1>
    <p>Color: {{ color }}</p>
    <p>Year: {{ year }}</p>
  </div>
</template>
<!-- src/App.vue -->
<Car brand="Ford" color="blue" :year="2020" />

Let op het verschil:

  • Strings als gewone attribuut: brand="Ford"
  • Numbers, booleans, arrays, objects met : (v-bind): :year="2020"

Zonder : wordt year="2020" behandeld als de string "2020".

Props met Arrays en Objects

<!-- src/components/Person.vue -->
<script setup>
defineProps(['name', 'hobbies'])
</script>

<template>
  <div>
    <h2>{{ name }}</h2>
    <ul>
      <li v-for="hobby in hobbies" :key="hobby">{{ hobby }}</li>
    </ul>
  </div>
</template>
<!-- Gebruik (let op de : voor de array): -->
<Person
  name="Jan"
  :hobbies="['voetbal', 'gamen', 'koken']"
/>

Zie het in actie — één component, drie keer gebruikt

Je schrijft StudentCard één keer. Daarna kun je hem zo vaak gebruiken als je wilt — telkens met andere props. Pas hieronder de props van elke kaart aan en kijk wat er gebeurt.

<script setup> defineProps(['name', 'role', 'avatar']) </script> <template> <div class="card"> <div class="avatar">{{ avatar }}</div> <h3>{{ name }}</h3> <p>{{ role }}</p> </div> </template>

Klik op een style-knop. Omdat er maar één definitie van StudentCard is, krijgen alle instances meteen de nieuwe styling.

De twee gezichten van props:

  1. Verschillende data per instance. Anna, Bram en Chloé hebben elk een eigen naam, rol en avatar — maar gebruiken dezelfde component.
  2. Eén styling voor alle instances. Verander de component één keer (klik op een style-knop) en alle drie de kaarten krijgen tegelijk de nieuwe look.

Dát is herbruikbaarheid. Schrijf het ontwerp één keer, gebruik het oneindig vaak met verschillende inhoud.

Props met Types (de betere manier)

Met een array (defineProps(['brand'])) is alles een any. Beter: gebruik een object en geef het type aan. Vue waarschuwt je dan in de console als er iets fout gaat.

<script setup>
defineProps({
  brand: String,
  year: Number,
  isElectric: Boolean,
  features: Array,
  owner: Object
})
</script>

Best Practice: Gebruik altijd het object-syntax met types. Je vangt fouten al tijdens development.

Default Values & Required

Met de object-syntax kun je ook defaults en verplichte props instellen:

<script setup>
defineProps({
  brand: {
    type: String,
    required: true       // moet meegegeven worden
  },
  color: {
    type: String,
    default: 'zwart'     // optioneel, met fallback
  },
  year: {
    type: Number,
    default: 2024
  }
})
</script>

Gebruik:

<Car brand="Ford" />
<!-- color wordt 'zwart', year wordt 2024 -->

Voor Arrays en Objects moet de default een functie zijn die de waarde teruggeeft:

defineProps({
  hobbies: {
    type: Array,
    default: () => []       // ✅ functie die [] teruggeeft
  }
})

Belangrijke Regels

  • Props zijn read-only — je kunt ze niet aanpassen in het child component
  • Props gaan van parent naar child — nooit andersom (gebruik emit voor de andere kant op)
  • Gebruik object-syntax met types in plaats van een array
  • Strings zonder :, alles anders met :

Veelgemaakte Fouten

Fout — Props aanpassen:

<script setup>
const props = defineProps(['brand'])
props.brand = 'Toyota'   // ❌ Niet doen!
</script>

Goed — Props zijn read-only:

<script setup>
const props = defineProps(['brand'])
// Gebruik props zonder ze aan te passen
</script>

<template>
  <h1>{{ brand }}</h1>
</template>

Fout — Number zonder ::

<Car year="2020" />  <!-- ❌ Dit is een string! -->

Goed — Number met : (v-bind):

<Car :year="2020" />  <!-- ✅ Dit is een number! -->

Fout — Default voor Array zonder functie:

defineProps({
  items: {
    type: Array,
    default: []      // ❌ Werkt niet voor objects/arrays
  }
})

Goed:

defineProps({
  items: {
    type: Array,
    default: () => []  // ✅ Functie die [] teruggeeft
  }
})