A List of Components

A real menu isn't written by hand, one <MenuItem> after another. It comes from data, and you show data with v-for, which works on components just as on elements:

<MenuItem v-for="item in menu" :key="item.id" :name="item.name" :price="item.price" />

Each item of menu gets its own MenuItem, with its own props. :key goes on the component, as it goes on an <li>: Vue uses it to tell the items apart. It isn't a prop, so the component doesn't declare it.

When a component needs most of an object, it's simpler to pass it the whole object, as one prop:

<MenuItem v-for="item in menu" :key="item.id" :item="item" />
<script setup>
defineProps({
    item: { type: Object, required: true },
});
</script>

<template>
    <li class="item">
        <span>{{ item.name }}</span>
        <span class="price">€{{ item.price }}</span>
    </li>
</template>

The prop's type is Object, and the template reads its fields as from any object: item.name. When the items of the menu get a new field, say vegan, the component can show it, and App.vue doesn't change at all.

And note the colon in :item="item". The item on the left is the name of the prop, and the one on the right is JavaScript: the variable item of v-for, the current item of the menu.

Instructions

  1. In App.vue, show the whole menu: in place of the one espresso, one <MenuItem> for each item of menu, with v-for, its :key and the props name and price.

  2. Now pass the whole item: give MenuItem one required prop item, an object, in place of name and price, and pass it with :item="item". An item with soldOut: true shows Sold out instead of its price, in the same <span class="price">.