Vue JS Directives and Event Handling 2 — Questions and Answers
Question 1: What does the `v-model` directive do on a native `<input>` element?
- Creates a two-way binding between the input's value and a data property (Correct answer)
- Validates the input's value
- Applies CSS styling to the input
- Renders a model/schema-based form
Correct answer: Creates a two-way binding between the input's value and a data property
`v-model` on `<input>` is syntactic sugar for `:value="data"` + `@input="data = $event.target.value"`, keeping the data and input in sync.
On a text input, `v-model` expands to `:value="name" @input="name = $event.target.value"`. For checkboxes it uses `checked` and `change`. For select it uses `value` and `change`. You can use modifiers: `.lazy` (sync on `change` instead of `input`), `.number` (coerce to number), `.trim` (trim whitespace). `v-model` works with any reactive value — ref, reactive property, or store state. On custom components, it binds to `modelValue` prop and listens for `update:modelValue` event.
Question 2: How do you apply multiple CSS classes conditionally using `v-bind:class`?
- :class="{ active: isActive, error: hasError }" (Correct answer)
- class="{{ isActive ? 'active' : '' }}"
- :class="isActive && 'active'"
- v-class="isActive: active"
Correct answer: :class="{ active: isActive, error: hasError }"
Object syntax for `:class` adds a class when its value is truthy. `{ active: isActive, error: hasError }` applies `active` when `isActive` is true and `error` when `hasError` is true.
Vue's `:class` binding supports three syntaxes: Object syntax (`{ active: isActive }`) adds classes when truthy. Array syntax (`[baseClass, conditionalClass]`) combines classes. Mixed: `[baseClass, { active: isActive }]`. `:class` merges with any static `class` attribute — you can use both on the same element. For inline styles, `:style` supports the same patterns. These syntaxes accept computed properties, making it easy to encapsulate complex class logic.
Question 3: What does the `.stop` event modifier do?
- Calls event.stopPropagation() to prevent the event from bubbling up to parent elements (Correct answer)
- Stops the Vue application from rendering
- Prevents further event handlers on the same element from running
- Cancels a pending async operation
Correct answer: Calls event.stopPropagation() to prevent the event from bubbling up to parent elements
`.stop` calls `event.stopPropagation()`, preventing the event from bubbling up through the DOM to parent elements' listeners.
DOM events bubble up through parent elements by default. `@click.stop` prevents the click event from reaching any parent element's click handlers. This is useful when a clickable element is inside another clickable element — clicking the inner element should not trigger the outer element's click handler. Note: `.stop` does NOT prevent other handlers on the same element (for that, you'd need `stopImmediatePropagation`). Chain with `.prevent` to stop both bubbling and default behavior.
Question 4: How does `v-bind` with an array work for the `class` attribute?
- :class="[baseClass, isActive ? 'active' : '']" applies all array items as classes (Correct answer)
- :class="[baseClass]" creates a CSS array property
- Arrays are not supported with v-bind:class
- :class="[baseClass]" iterates and renders class elements
Correct answer: :class="[baseClass, isActive ? 'active' : '']" applies all array items as classes
Array syntax for `:class` allows applying multiple classes. String items are always applied; conditional classes use ternary expressions or nested objects within the array.
`:class="['base-class', isActive ? 'active' : '', { 'text-danger': hasError }]"` combines static strings, ternary expressions, and object syntax within one array. This is useful when you have both unconditional and conditional classes. The `class` binding is additive — it merges with any static `class` attribute on the same element. For complex class logic, compute the array in a computed property and bind to that: `:class="classArray"` where `classArray` is a computed value.
Question 5: What is the purpose of key modifiers in Vue 3 event handling, e.g., `@keyup.enter`?
- They filter keyboard events to only fire the handler when the specified key is pressed (Correct answer)
- They define keyboard shortcuts for the application
- They bind keyboard events to native DOM properties
- They prevent default behavior for specific keys
Correct answer: They filter keyboard events to only fire the handler when the specified key is pressed
Key modifiers filter keyboard events. `@keyup.enter` only calls the handler when the Enter key is released, avoiding the need for manual `event.key` checks in the handler.
Vue 3 supports key modifiers for `keyup`, `keydown`, and `keypress` events. Common modifiers: `.enter`, `.tab`, `.delete`, `.esc`, `.space`, `.up`, `.down`, `.left`, `.right`. System modifiers: `.ctrl`, `.alt`, `.shift`, `.meta` (Command on Mac). You can chain them: `@keyup.ctrl.enter` fires only when Ctrl+Enter is released. For exact key combinations: `@keyup.exact.ctrl` fires only when Ctrl alone is pressed (not Ctrl+Alt). Custom key names use kebab-case of `KeyboardEvent.key`: `@keyup.page-down`.
Question 6: In Vue 3, how do you bind an inline event handler that passes both the event object and a custom argument?
- @click="handleClick($event, myArg)" (Correct answer)
- @click="handleClick(event, myArg)"
- @click.event="handleClick(myArg)"
- @click="handleClick" :arg="myArg"
Correct answer: @click="handleClick($event, myArg)"
When you need to pass custom arguments along with the native event object in an inline handler, Vue provides the `$event` special variable to access the event.
Vue uses `$event` as a special variable in inline event handlers to access the native DOM event. `@click="handleClick($event, myArg)"` passes both the event and your custom argument to the method. Without `$event`, `handleClick(myArg)` only passes your argument and the method cannot access the event. Alternatively, use an arrow function: `@click="(e) => handleClick(e, myArg)"`. Both approaches work; the arrow function syntax is more explicit about what's happening.
What does the `v-model` directive do on a native `` element?