codejump

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

Waiting at the end of this page.

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:

JavaScript
// 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:

JavaScript
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:

vue
<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 drills

Reading this page is the cheap half. These are the exercises that make you use it.