AcademyVue
Props & Component Events
Props flow down, events flow up — and the object syntax for both is what actually gives you defaults, validation and v-model.
2 min readUpdated 3 exercises
The object syntax is what makes props real
Vue accepts two shapes for props: an array of names, or an object describing each one. Only the object form does anything beyond declaring that a name exists:
// Array syntax — a name list, nothing more. No default, no required
// check, no type coercion.
props: ['count', 'label']
// Object syntax — type, default and required are all real behavior
props: {
count: { type: Number, default: 0 },
label: { type: String, required: true },
}Omit count with the array form and it is undefined inside the component. Omit it with the object form and it is 0, exactly as declared — the difference between a prop that behaves as documented and one that is a name with no contract behind it.
A component's events are its half of the conversation
Props are how a parent talks to a child; emit is how the child talks back. Declaring emits — again, the object form over the array form — documents and validates what a component promises to say:
const SearchBox = defineComponent({
emits: {
search: (value) => typeof value === 'string',
},
setup(_, { emit }) {
return () => h('input', {
onInput: (e) => emit('search', e.target.value),
})
},
})The event name matters exactly as much as its spelling: a parent listening with @search hears nothing from a child that emits 'update' or 'Search' — two strings that only look related.
v-model on a component is that same mechanism, named a specific way
v-model="count" on a component desugars to binding a modelValue prop and listening for an update:modelValue event — nothing magic, the exact prop/emit pair from above with one specific, conventional name:
<Stepper v-model="count" />
<!-- desugars to -->
<Stepper :model-value="count" @update:model-value="count = $event" />Emit anything other than 'update:modelValue' from inside Stepper and the parent's v-model simply never updates — there is no special-cased fallback, only that one event name being listened for.
What interviewers check
Whether you can explain v-model on a component without reaching for "it's magic" — it is exactly the prop/emit pattern above, with one name Vue has agreed to treat as the default. Naming that name (modelValue / update:modelValue) is usually the tell for whether someone has actually built a component that uses it.
Now practice it
1 quiz · 2 drillsReading this page is the cheap half. These are the exercises that make you use it.
- PropsProArray-style props accept anything and apply no default — the exact gap the object syntax closes.DrillSolve · MediumDrillSolve · Medium
- Component Events & v-modelProA Stepper wrapped in v-model that never updates, because it emits the wrong event name.DrillSolve · MediumDrillSolve · Medium
- Options API · Options API Deep-diveOptions API props and custom events work the same underneath — this set checks the same contract from that angle.QuizTake · MediumQuizTake · Medium
Read next
Slots: Passing Templates, Not Just Values
A slot is a function a parent hands its child — calling it renders the parent's markup, and calling it with data makes that markup scoped.
2 min
Fallthrough Attributes
An attribute a parent passes but the child never declares as a prop lands on the root element automatically — unless there is more than one root.
2 min