One Source of Truth

The order gets a component of its own, OrderList. Order something, though, and it still says Nothing ordered yet. That's because OrderList has an order of its own:

<script setup>
import { ref } from "vue";

const order = ref([]);
</script>

App.vue adds the items to its order, and OrderList shows its own: a second array, which nobody adds anything to. Two copies of the same data, and the page shows the wrong one.

The same thing goes wrong when a component keeps something to itself that other parts of the page need too. If MenuItem counted its orders in its own const count = ref(0);, the item would say ×2, and the order and its total wouldn't know.

So each piece of data lives in one place, its one source of truth. When several components need it, it lives in their common parent, here App.vue. The parent passes it as a prop to the components that show it, and they ask for changes with events:

App.vue          has order and changes it in addToOrder()
├── MenuItem     emits order, and App.vue adds the item
└── OrderList    gets :order="order" and shows it

Moving data up into the parent like this is called lifting state up. Only App.vue changes order, and both components always show the same order, because there's only one.

Instructions

  1. In OrderList.vue, replace the component's own order with a required prop order, an array. In App.vue, pass it the order. What you order now shows in the order.

  2. Under the list, OrderList shows the total in a <p class="total">: for an espresso and a green tea, Total: €5. It's each item's price times its count, all added up. Use a computed value.