# Props and Emits — Vue.js

Source: https://www.skillbyai.com/en/vue/c-props

> 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.

![Three ideas: props and emits, component v-model, slots.](assets/figures/vue/section-3-map.svg) — Figure 3.1 — Props down, events up, slots for content.

## A child component with props and an event

TodoItem.vue and its use in a parent.

```vue
<!-- 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.

**Quiz:** How should a child component request a change to data it received as a prop?

- [x] 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.
