Vue JS Components and Props 2 — Questions and Answers
Question 1: Which of the following is a valid way to register a child component locally in Vue 3 Options API?
- components: { MyButton } (Correct answer)
- import MyButton and use directly in template
- register('MyButton')
- Vue.component('MyButton', MyButton)
Correct answer: components: { MyButton }
Local component registration in Options API is done via the `components` option object. The component is only available inside that parent component.
In Vue 3's Options API, components are registered locally by listing them in the `components` option: `components: { MyButton }`. This is ES6 shorthand for `{ MyButton: MyButton }`. The component is then available in that component's template as `<MyButton />` or `<my-button />`. Local registration is preferred over global because it keeps the bundle size smaller and makes dependency relationships explicit. In `<script setup>`, imported components are automatically available without registration.
Question 2: What is a slot in Vue 3?
- A mechanism to pass template content from parent to child (Correct answer)
- A reactive state variable
- A lifecycle hook
- A way to register global components
Correct answer: A mechanism to pass template content from parent to child
Slots allow parent components to inject HTML or template content into a child component's designated `<slot>` placeholders.
Vue slots are inspired by the Web Components slot element. A child component places `<slot></slot>` tags in its template to define insertion points. The parent component then provides content between the child's opening and closing tags, which gets rendered in place of the `<slot>`. Named slots allow multiple insertion points: `<slot name="header">` and `<template #header>`. Scoped slots let child components pass data back to the parent's slot content.
Question 3: When a prop's default value needs to be an object or array, how should you declare it in Vue 3?
- As a factory function: default: () => ({}) (Correct answer)
- As a plain object: default: {}
- As a string: default: '{}'
- Objects cannot be prop defaults
Correct answer: As a factory function: default: () => ({})
Objects and arrays as prop defaults must be returned from a factory function to avoid sharing the same reference across all component instances.
In JavaScript, objects and arrays are reference types. If you write `default: {}`, every component instance would share the same default object, leading to unintended mutations affecting all instances. Vue 3 requires you to use a factory function: `default: () => ({})`. This ensures each instance gets its own fresh copy. Vue will warn you if you use a non-function default for object or array types.
Question 4: How do you emit a custom event from a child component in Vue 3 Composition API (`<script setup>`)?
- const emit = defineEmits(['update']); emit('update', value) (Correct answer)
- this.$emit('update', value)
- Vue.emit('update', value)
- emits: ['update']; this.emit('update', value)
Correct answer: const emit = defineEmits(['update']); emit('update', value)
`defineEmits` is the Composition API compiler macro for declaring emits in `<script setup>`, and the returned `emit` function is used to trigger events.
Inside `<script setup>`, you use `const emit = defineEmits(['update'])` to declare the events your component can emit. The returned `emit` function works the same as `this.$emit` in Options API. You call `emit('update', newValue)` to dispatch the event. Declaring events with `defineEmits` provides documentation, enables type checking in TypeScript, and allows Vue to correctly handle `v-model` and event modifiers.
Question 5: What is the purpose of the `key` attribute when rendering lists of components?
- It helps Vue identify which components have changed and need to be re-rendered (Correct answer)
- It sets a CSS class on each component
- It provides an ID for direct DOM access
- It controls the order of rendering
Correct answer: It helps Vue identify which components have changed and need to be re-rendered
The `key` attribute gives Vue a hint to track each node's identity across re-renders, enabling efficient DOM diffing and correct component reuse.
When Vue re-renders a list, it uses the `key` attribute to match nodes between the old and new virtual DOM trees. Without unique keys, Vue uses an in-place patch strategy that may reuse component instances incorrectly, leading to bugs especially with stateful components or inputs. With a stable unique `key` (like an `id`), Vue can move, add, or remove DOM nodes precisely. You should always provide a key when using `v-for`, ideally a stable, unique identifier from your data.
Question 6: Which prop modifier in Vue 3 makes `v-model` work on a custom component with a non-default prop name?
- v-model:propName (Correct answer)
- v-bind:propName.sync
- v-model.propName
- v-bind:modelValue
Correct answer: v-model:propName
Vue 3's `v-model:propName` syntax allows binding `v-model` to a specific prop name on a custom component, enabling multiple v-model bindings.
In Vue 3, `v-model` on a component expands to `:modelValue` + `@update:modelValue` by default. To use a different prop name, you add an argument: `v-model:title` expands to `:title` + `@update:title`. This also allows multiple v-model bindings on one component: `v-model:firstName` and `v-model:lastName`. The child component receives `title` as a prop and emits `update:title` to sync changes back, all declared with `defineProps` and `defineEmits`.
Which of the following is a valid way to register a child component locally in Vue 3 Options API?