Lesson 7 / 25
Props and Emits
Data down, events up.
One-way data flow
A parent passes data to a child through props, declared in <script setup> with the compiler macro defineProps (no import needed). Props are read-only in the child: if the child needs to change something, it emits an event declared with defineEmits, and the parent decides what to do. This one-way flow keeps it clear which component owns each piece of state. Props can be declared with runtime options (type, required, default) or, with TypeScript, with a type argument. Emitted event names are written in camelCase in script and usually listened to in kebab-case in templates.
Composing the UI from pieces
Components receive data through props, report changes with events, and let parents supply content through slots.
A child component with props and an event
TodoItem.vue and its use in a parent.
<!-- TodoItem.vue -->
<script setup>
const props = defineProps({
text: { type: String, required: true },
done: { type: Boolean, default: false },
})
const emit = defineEmits(['toggle', 'remove'])
</script>
<template>
<li :class="{ done: props.done }">
<input type="checkbox" :checked="done" @change="emit('toggle')" />
{{ text }}
<button @click="emit('remove')">x</button>
</li>
</template>
<!-- Parent.vue (template part) -->
<!-- <TodoItem v-for="t in todos" :key="t.id" :text="t.text" :done="t.done"
@toggle="t.done = !t.done" @remove="removeTodo(t.id)" /> -->A manager and a team member
The manager (parent) hands over the brief (props); the team member does not rewrite the brief but reports back (emits) and lets the manager decide.
Quick check: How should a child component request a change to data it received as a prop?
- Emit an event so the parent updates its own state
- Assign a new value to the prop
- Use v-html on the prop
- Call the parent component method directly by name
Answer
Emit an event so the parent updates its own state — Props are read-only in the child.