Summary
In this lesson, you learned that:
- A component can't change its parent's data. It tells the parent that something happened with an event:
const emit = defineEmits(["order"]);declares it, andemit("order", item.id)emits it, in the script or right in the template,@click="emit('order', item.id)". - The parent listens with
@order="addToOrder", and the event's values become the handler's arguments:emit("change-count", item.id, 1)callschangeCount(id, change). - Events are named after what happened or what the component asks for, in its own words, and names of several words are written in kebab-case:
change-count. - Each piece of data has one source of truth. When several components need it, it lives in their common parent, which passes it to them as props and changes it when they ask with events. That's lifting state up. A copy in a component, its own ref, goes out of date.
- A component that changes its prop gets
[Vue warn]: Set operation on key "count" failed: target is readonly., and nothing changes: it has to emit an event. v-modelworks on your own components:<Quantity v-model="count" />in the parent,const count = defineModel();in the component. Changing the model changes the parent's value, and the model can go on to a field inside,<textarea v-model="note">.
In the next lesson, Slots, you'll pass a component not just values, but a piece of the template: content between its tags, as you do with HTML elements.
But first, a little practice: the barista's list of orders to make. Ticket.vue has only its style, and you'll write the rest yourself.
Instructions
- 1
In
Ticket.vue, write a component with a propticket, an object, required. It shows an<li class="ticket">with the customer's name and the drink, as inAnna: Cappuccino, and a buttonDone. InApp.vue, import it and show aTicketfor each ticket inqueue. - 2
A click on Done emits
donewith the ticket'sid, andApp.vueremoves the ticket fromqueue. When all tickets are done, the page shows All done!, which is in the template already.