Good Code
The good version names the input fields and the event payload. The parent can see exactly which action the child requests.
Lesson 02
Declare props and emitted events so parent and child components agree on their data contract.
<script setup lang="ts">
const props = defineProps<{
reviewId: string;
canApprove: boolean;
}>();
const emit = defineEmits<{
approve: [reviewId: string];
}>();
// The child asks the parent to change state through a named event.
function approveReview() {
emit("approve", props.reviewId);
}
</script>
<template>
<button :disabled="!canApprove" @click="approveReview">
Approve
</button>
</template><script setup>
const props = defineProps(["review"]);
// Mutating a prop hides the parent-child data flow.
function approveReview() {
props.review.status = "approved";
}
</script>
<template>
<button @click="approveReview">
Approve
</button>
</template>The good version names the input fields and the event payload. The parent can see exactly which action the child requests.
The bad version mutates a prop object directly. That makes ownership unclear and can leave the parent, store, or cache out of sync.