Vue Component Props

By

Learn how Vue 3 props pass data from parent to child, including defineProps, types, defaults, required props, and camelCase vs kebab-case in templates.

~~~

Define a prop inside the component

Props are how a child component receives data from its parent.

Declare them before you use them.

With <script setup> and defineProps (the usual Vue 3 style in SFCs):

<template>
  <p>Hi {{ name }}</p>
</template>

<script setup>
defineProps(['name'])
</script>

With the Options API:

<template>
  <p>Hi {{ name }}</p>
</template>

<script>
export default {
  props: ['name']
}
</script>

Or when you register a component on the app:

import { createApp } from 'vue'

const app = createApp({})

app.component('UserName', {
  props: ['name'],
  template: '<p>Hi {{ name }}</p>'
})

app.mount('#app')

Accept multiple props

List every prop you expect:

defineProps(['firstName', 'lastName'])
export default {
  props: ['firstName', 'lastName']
}

Set the prop type

Use an object form to declare types:

defineProps({
  firstName: String,
  lastName: String
})

Valid types:

In development, Vue warns when the runtime type does not match.

Allow more than one type:

defineProps({
  firstName: [String, Number]
})

Set a prop to be mandatory

defineProps({
  firstName: {
    type: String,
    required: true
  }
})

Set the default value of a prop

defineProps({
  firstName: {
    type: String,
    default: 'Unknown person'
  }
})

For objects and arrays, default must be a factory function. Otherwise every instance would share the same reference:

defineProps({
  name: {
    type: Object,
    default() {
      return {
        firstName: 'Unknown',
        lastName: ''
      }
    }
  }
})

You can also write a custom validator:

defineProps({
  name: {
    validator(value) {
      return value === 'Flavio'
    }
  }
})

Passing props to the component

Static string:

<UserName name="Flavio" />

From parent state, use v-bind / ::

<template>
  <UserName :name="name" />
</template>

<script setup>
import { ref } from 'vue'
import UserName from './UserName.vue'

const name = ref('Flavio')
</script>

In JavaScript, prop names are camelCase (firstName). In DOM templates, use kebab-case (first-name). Vue maps them:

<UserName first-name="Flavio" last-name="Copes" />
defineProps({
  firstName: String,
  lastName: String
})

In Single File Component templates (compiled), camelCase in the template is fine too.

Props are one-way: parent to child. When the parent updates the prop, the child sees the new value. Do not mutate a prop inside the child. Emit an event, or use a local copy, if the child needs to request a change. More on that in component communication.

You can use an expression when binding:

<ColorBox :colored="color === 'white'" />
Tagged: Vue.js · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about vue: