Skip to content

Vue Props

In Vue, parent components pass data to child components through Props. Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property of that component instance.

Passing Props

Suppose we have a blog post component BlogPost.vue, and we want to pass the post's title to it from the parent component App.vue.

BlogPost.vue (Child Component)

vue
<script setup>
// Use the defineProps macro to declare props
const props = defineProps(['title'])

// props.title can be accessed in both template and script
console.log(props.title)
</script>

<template>
  <h4>{{ title }}</h4>
</template>

App.vue (Parent Component)

vue
<script setup>
import BlogPost from './BlogPost.vue'
</script>

<template>
  <BlogPost title="My journey with Vue" />
  <BlogPost title="Blogging with Vue" />
  <BlogPost title="Why Vue is so fun" />
</template>

In this example:

  1. The child component BlogPost.vue uses the defineProps(['title']) macro to declare that it receives a prop named title.
  2. The parent component App.vue passes a string to the title prop when using the <BlogPost> component, similar to passing HTML attributes.

Prop Naming Rules

  • CamelCase vs. kebab-case: In JavaScript, prop names typically use camelCase, like greetingText. But in HTML attributes, it's recommended to use kebab-case, like greeting-text. Vue automatically handles the conversion between these two naming styles.

    js
    // In JS
    defineProps(['greetingText'])
    html
    <!-- In HTML -->
    <MyComponent greeting-text="hello" />

Dynamic Props

Similar to binding normal HTML attributes, we can also use v-bind (or its shorthand :) to dynamically pass props.

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

const posts = ref([
  { id: 1, title: 'My journey with Vue' },
  { id: 2, title: 'Blogging with Vue' },
  { id: 3, title: 'Why Vue is so fun' }
])
</script>

<template>
  <BlogPost
    v-for="post in posts"
    :key="post.id"
    :title="post.title"
  />
</template>

Prop Validation

Components can specify validation requirements for props, such as type checking. If the passed value doesn't meet the requirements, Vue will give a warning in the browser console.

To specify validation, you can provide an object with validation requirements to defineProps instead of a string array.

vue
<script setup>
defineProps({
  // Basic type check
  // (`null` and `undefined` will pass any type validation)
  propA: Number,
  // Multiple possible types
  propB: [String, Number],
  // Required string
  propC: {
    type: String,
    required: true
  },
  // Number with default value
  propD: {
    type: Number,
    default: 100
  },
  // Object with default value
  propE: {
    type: Object,
    // Object or array defaults must be returned from a factory function
    default: () => ({ message: 'hello' })
  },
  // Custom validation function
  propF: {
    validator: (value) => {
      // This value must match one of the following strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  }
})
</script>

One-Way Data Flow

All props create a one-way down binding between parent and child props: updates from parent props flow down to child components, but not vice versa. This prevents the child component from accidentally mutating the parent component's state, which would make your application's data flow difficult to understand.

Each time the parent component updates, all props in the child component will refresh to the latest values. This means you should not modify a prop inside a child component. If you do this, Vue will give a warning in the console.

Content is for learning and research only.