How do parent and child components communicate in Vue?
Quick Answer
Data flows down via props and events flow up via emit. A parent passes data to a child as props (read-only in the child); the child asks the parent to change something by emitting an event (emit('update')). v-model on a component is sugar for a prop plus an update:modelValue event.
The rule is props down, events up. The parent passes data to the child as props, and the child treats those as read-only. When the child needs something changed, it emits an event and the parent, which owns the data, updates it. v-model on a custom component is just that pattern packaged up — a modelValue prop and an update:modelValue event. For passing data through many layers I'd use provide/inject or a Pinia store rather than drilling props all the way down.
- Props down:
<UserCard :user="selected" />. The child must not mutate a prop — that breaks one-way flow and Vue warns. - Events up:
emit('delete', user.id); parent handles@delete="remove". - Two-way on a component:
v-model:title="page.title"⇄ proptitle+emit('update:title', ...). - Deeper trees:
provide/injectfor ancestor→descendant without prop-drilling; a store (Pinia) for shared app state; refs /defineExposefor direct method calls.