Vue JS Directives and Event Handling 1 — Questions and Answers
Question 1: What is the purpose of the `v-if` directive in Vue 3?
- Conditionally renders an element based on a truthy expression; the element is added/removed from the DOM (Correct answer)
- Hides an element with CSS display:none
- Toggles a CSS class on an element
- Conditionally applies a v-bind binding
Correct answer: Conditionally renders an element based on a truthy expression; the element is added/removed from the DOM
`v-if` conditionally renders elements by actually adding or removing them from the DOM. When false, the element and its component are destroyed.
`v-if` causes Vue to add or remove the element (and all its children/components) from the DOM based on the expression's truthiness. When the condition becomes false, the component's lifecycle hooks (`beforeUnmount`, `unmounted`) are called and the component is destroyed. When it becomes true again, the component is re-created. This makes `v-if` more expensive for frequent toggling but more efficient when the condition rarely changes. Use with `v-else-if` and `v-else` for chained conditions.
Question 2: What is the difference between `v-if` and `v-show`?
- `v-if` adds/removes elements from the DOM; `v-show` toggles CSS `display` property only (Correct answer)
- `v-show` supports v-else; `v-if` does not
- `v-if` only works on components; `v-show` works on HTML elements
- They are identical in behavior
Correct answer: `v-if` adds/removes elements from the DOM; `v-show` toggles CSS `display` property only
`v-show` always renders the element but controls visibility with `display: none`. `v-if` actually mounts/unmounts the element and its component lifecycle.
The choice between `v-if` and `v-show` is a trade-off: `v-show` has a higher initial render cost (always renders) but cheap toggle cost (just changes CSS). `v-if` has a low initial cost when false (not rendered at all) but higher toggle cost (destroys and re-creates the component). Use `v-show` for elements that toggle frequently (modals, tooltips). Use `v-if` for elements that are rarely shown or should not be rendered at all in certain contexts (auth-gated content, heavy components).
Question 3: How do you listen to a DOM click event and call a method in Vue 3?
- <button @click="handleClick">Click</button> (Correct answer)
- <button v-on-click="handleClick">Click</button>
- <button onclick="handleClick">Click</button>
- <button v-click="handleClick">Click</button>
Correct answer: <button @click="handleClick">Click</button>
`@click` is the shorthand for `v-on:click`. It binds a Vue event listener that calls `handleClick` when the button is clicked.
Vue's `v-on` directive attaches event listeners to elements. The full syntax is `v-on:click="handler"` and the shorthand is `@click="handler"`. The handler can be a method name, an inline handler, or an inline statement. To access the native event object in an inline handler, use `$event`: `@click="handleClick($event, param)"`. Vue automatically cleans up event listeners when components are unmounted, preventing memory leaks.
Question 4: What does the `.prevent` event modifier do in Vue 3?
- Calls event.preventDefault() on the event (Correct answer)
- Stops event propagation to parent elements
- Prevents the event from firing more than once
- Prevents the browser from scrolling
Correct answer: Calls event.preventDefault() on the event
`.prevent` calls `event.preventDefault()`, which prevents the browser's default action for the event (e.g., stopping form submission or link navigation).
Vue event modifiers let you handle common event operations declaratively. `@submit.prevent` is equivalent to `@submit="e => e.preventDefault()"` but cleaner. Common modifiers: `.stop` (stopPropagation), `.prevent` (preventDefault), `.once` (fires only once), `.capture` (uses capture mode), `.self` (only fires if target is the element itself), `.passive` (marks the listener as passive for scroll performance). Modifiers can be chained: `@click.stop.prevent`.
Question 5: How do you use `v-for` to render a list and what must you always include?
- <li v-for="item in items" :key="item.id">{{ item.name }}</li> — always include a unique :key (Correct answer)
- <li v-each="item in items">{{ item.name }}</li>
- <li v-loop="item of items">{{ item.name }}</li>
- <li v-repeat="item in items">{{ item.name }}</li>
Correct answer: <li v-for="item in items" :key="item.id">{{ item.name }}</li> — always include a unique :key
`v-for="item in items"` iterates over the `items` array. The `:key` attribute is required for Vue to efficiently track and reorder list items.
`v-for` iterates over arrays (`item in array`), objects (`(value, key, index) in object`), or a range (`n in 10`). Always provide a stable unique `:key` — typically an item's database ID. The key helps Vue's virtual DOM diffing algorithm minimize DOM operations when the list changes. Without keys, Vue uses in-place patch, which can cause bugs with stateful components. `v-for` has higher priority than `v-if` when on the same element, but avoid combining them — use `v-if` on a wrapper element instead.
Question 6: What is a custom directive in Vue 3 and how do you register one?
- An object with lifecycle hooks (mounted, updated, etc.) registered via app.directive('name', directiveObj) (Correct answer)
- A component that acts like a built-in directive
- A Composition API composable that starts with v-
- A plugin that extends Vue's directive system
Correct answer: An object with lifecycle hooks (mounted, updated, etc.) registered via app.directive('name', directiveObj)
Custom directives are objects with optional lifecycle hooks (mounted, updated, etc.) registered globally with `app.directive` or locally in the component's `directives` option.
A custom directive is an object with hooks: `const vFocus = { mounted(el) { el.focus() } }`. Global registration: `app.directive('focus', vFocus)`. Local registration in `<script setup>`: any variable named with a `v` prefix is automatically available as a directive: `const vFocus = { mounted: el => el.focus() }` → `<input v-focus>`. Directive hooks receive `(el, binding, vnode, prevVnode)`. Available hooks: `created`, `beforeMount`, `mounted`, `beforeUpdate`, `updated`, `beforeUnmount`, `unmounted`. The hook names mirror component lifecycle hooks.
What is the purpose of the `v-if` directive in Vue 3?