0Pricing
Frontend Academy · Lesson

Component Props and Emits

Pass data down with defineProps, emit events up with defineEmits, and validate props with type and required constraints.

Component Props and Emits is a free Frontend Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Props in Vue 3

Props pass data from parent to child. In <script setup>, use defineProps() to declare them. Props are read-only in the child — never mutate them directly.

<script setup lang="ts">
const props = defineProps<{
  title: string;
  count?: number;
  variant?: 'primary' | 'secondary';
}>();
</script>

<template>
  <h2>{{ title }} ({{ count ?? 0 }})</h2>
</template>

withDefaults for Prop Defaults

Wrap defineProps() with withDefaults() to supply default values.

<script setup lang="ts">
const props = withDefaults(defineProps<{
  count?: number;
  variant?: 'primary' | 'secondary';
}>(), {
  count: 0,
  variant: 'primary'
});
</script>

Passing Props in the Template

Pass static values as plain attributes. Pass dynamic values with v-bind (:). Pass boolean attributes as presence (no value).

<MyButton title="Submit" :count="activeCount" variant="primary" />
<Toggle :disabled="isLoading" />

Emits — Child to Parent Communication

Children communicate upward by emitting events. Use defineEmits() to declare what events the component can emit, then call the returned emit function.

<script setup lang="ts">
const emit = defineEmits<{
  update: [value: string];
  close: [];
  submit: [data: FormData];
}>();

function handleSubmit(data: FormData) {
  emit('submit', data); // fire the event
}
</script>

Listening to Emits in the Parent

Use @eventName in the template to listen for custom events from child components.

<SearchInput
  @update="searchTerm = $event"
  @submit="handleSearch"
/>

v-model with Custom Components

v-model on a custom component is shorthand for :modelValue + @update:modelValue. The component must accept the prop and emit the update event.

<!-- Parent: -->
<MyInput v-model="email" />

<!-- MyInput.vue: -->
<script setup lang="ts">
defineProps<{ modelValue: string }>();
const emit = defineEmits<{ 'update:modelValue': [string] }>();
</script>

<template>
  <input :value="modelValue" @input="emit('update:modelValue', ($event.target as HTMLInputElement).value)" />
</template>

Multiple v-model Bindings

Vue 3 supports multiple v-model on one component with named modifiers.

<UserForm v-model:firstName="user.firstName" v-model:lastName="user.lastName" />

Prop Validation

In the Options API or runtime props declaration, add type, required, and validator constraints. TypeScript-based defineProps() provides this at compile time.

Prop vs Data — One-Way Flow

Vue enforces one-way data flow: props flow from parent to child; events flow from child to parent. If a child needs to modify data, it emits an event and the parent handles the update.

Slots as an Alternative to Props

For content that should be HTML/components (not just data), use slots. The parent provides the content inside the component's tags; the child renders it with <slot />.

<!-- Parent: -->
<Card title="Hello">
  <p>This content goes in the default slot.</p>
</Card>

<!-- Card.vue: -->
<template>
  <div class="card">
    <h2>{{ title }}</h2>
    <slot />  <!-- renders the p tag -->
  </div>
</template>

Quick Check

How does a child Vue component communicate an event back to its parent?

Recap: Props and Emits

defineProps for typed prop declarations. withDefaults for default values. Props are read-only in children. defineEmits to declare and type emitted events. @eventName in parent to listen. v-model = :modelValue + @update:modelValue. One-way data flow: props down, events up. Slots for passing content/template fragments.

Frequently asked questions

Is the “Component Props and Emits” lesson free?

Yes — the full text of “Component Props and Emits” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.

What will I learn in “Component Props and Emits”?

Pass data down with defineProps, emit events up with defineEmits, and validate props with type and required constraints. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Frontend Academy?

No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Component Props and Emits” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Frontend Academy lesson?

Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Vue SFC: script template style
  2. Options API: data methods computed
  3. Directives: v-if v-for v-bind v-on
  4. Component Props and Emits
← Back to Frontend Academy