Bind class with object syntax
Use :class with an object to dynamically toggle classes. The presence of each class is determined by the truthiness of the corresponding property value. Example: <div :class="{ active: isActive }"></div> will add the 'active' class when isActive is truthy.
Bind class with array syntax
Use :class with an array to apply a list of classes. Example: <div :class="[activeClass, errorClass]"></div> applies multiple classes from variables.
Bind inline styles with object
:style supports binding to JavaScript object values corresponding to HTML element's style property. Example: <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> dynamically applies inline styles.
Conditional class in array binding
Use a ternary expression within an array bound to :class to conditionally include a class. Example: <div :class="[isActive ? activeClass : '', errorClass]"></div> applies errorClass always but activeClass only when isActive is truthy.
CSS property naming in style binding
Both camelCase and kebab-cased CSS property keys are supported in :style bindings. camelCase keys are recommended. Example: both <div :style="{ fontSize: fontSize + 'px' }"></div> and <div :style="{ 'font-size': fontSize + 'px' }"></div> work correctly.
Bind style to object directly
Bind :style directly to a style object for cleaner templates. Example: <div :style="styleObject"></div> where styleObject is { color: 'red', fontSize: '30px' }. This pattern works well with computed properties that return objects.
Bind style to array of objects
Bind :style to an array of multiple style objects. These objects will be merged and applied to the same element. Example: <div :style="[baseStyles, overridingStyles]"></div>.
Multiple classes with object binding
An object bound to :class can have multiple fields to toggle multiple classes. The :class directive can coexist with a plain class attribute. Example: <div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div> renders with both static and dynamic classes merged.
Coexist style attribute with :style directive
:style directives can coexist with regular style attributes. Example: <h1 style="color: red" :style="'font-size: 1em'">hello</h1> renders as <h1 style="color: red; font-size: 1em;">hello</h1> with both styles merged.
Auto-prefixing vendor prefixes in styles
When using a CSS property requiring a vendor prefix in :style, Vue automatically adds the appropriate prefix by checking at runtime which style properties are supported in the current browser. If a property is not supported, Vue tests various prefixed variants to find one that is supported.
Multiple values for style property with browser fallback
Provide an array of multiple (prefixed) values to a style property for browser compatibility. Example: <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div> renders only the last value in the array which the browser supports.
Use computed property with class object binding
Bind :class to a computed property that returns an object for a common and powerful pattern. Example: computed(() => ({ active: isActive.value && !error.value, 'text-danger': error.value && error.value.type === 'fatal' })) allows complex class logic.
Object syntax inside array class binding
Combine object and array syntax for :class to avoid verbose ternary expressions. Example: <div :class="[{ [activeClass]: isActive }, errorClass]"></div> conditionally applies activeClass when isActive is truthy while always applying errorClass.
v-else directive
The v-else directive indicates an else block for v-if. A v-else element must immediately follow a v-if or v-else-if element, otherwise it will not be recognized.
v-show directive
The v-show directive conditionally displays an element by toggling the display CSS property. An element with v-show will always be rendered and remain in the DOM, unlike v-if which removes it from the DOM. v-show does not support the <template> element and does not work with v-else.
v-if and v-for precedence
When v-if and v-for are both used on the same element, v-if will be evaluated first. Using both on the same element is not recommended due to implicit precedence.
v-if directive for conditional rendering
The v-if directive is used to conditionally render a block of content. The block will only be rendered if the directive's expression returns a truthy value.
v-if is real conditional rendering
v-if ensures that event listeners and child components inside the conditional block are properly destroyed and re-created during toggles, making it true conditional rendering.
v-if on template element
Since v-if is a directive that must be attached to a single element, you can use v-if on a <template> element to toggle multiple elements at once. The <template> element serves as an invisible wrapper and will not be included in the final rendered result. v-else and v-else-if can also be used on <template>.
v-else-if directive
The v-else-if directive serves as an else if block for v-if and can be chained multiple times. A v-else-if element must immediately follow a v-if or v-else-if element.
Modifier-only event handlers
You can use only a modifier without a handler method. Example: <form @submit.prevent></form> will prevent form submission without calling any handler.
Event modifiers available
Vue provides the following event modifiers for v-on: .stop (stops click propagation), .prevent (prevents default action), .self (only trigger if event.target is the element itself, not from children), .capture (uses capture mode when adding event listener), .once (triggers at most once), .passive (allows default behavior to happen immediately without waiting for handler to complete).
Key aliases in Vue
Vue provides aliases for commonly used keys: .enter, .tab, .delete (captures both Delete and Backspace), .esc, .space, .up, .down, .left, .right.
Method handlers receive DOM event object
A method handler automatically receives the native DOM Event object that triggers it. The handler can access properties like event.target to get the element that dispatched the event.
Method vs inline detection logic
The template compiler detects method handlers by checking whether the v-on value string is a valid JavaScript identifier or property access path. Examples treated as method handlers: foo, foo.bar, foo['bar']. Examples treated as inline handlers: foo(), count++.
Accessing native event in inline handlers with $event
Use the special $event variable to pass the native DOM event into a method called from an inline handler. Example: <button @click="warn('message', $event)">Submit</button>. Alternatively, use an inline arrow function: <button @click="(event) => warn('message', event)">Submit</button>.
Inline handlers example
Inline handlers execute JavaScript directly. Example: <button @click="count++">Add 1</button> will increment count when clicked.
Calling methods with custom arguments in inline handlers
You can call methods in an inline handler to pass custom arguments instead of the native event. Example: <button @click="say('hello')">Say hello</button> calls the say method with 'hello' as an argument.
Two types of event handlers
Handler values can be either inline handlers (inline JavaScript executed when the event is triggered, similar to the native onclick attribute) or method handlers (a property name or path pointing to a method defined on the component).
Key modifiers for keyboard events
When listening for keyboard events, you can check for specific keys using key modifiers. Use any valid key name from KeyboardEvent.key as a modifier by converting it to kebab-case. Example: <input @keyup.page-down="onPageDown" /> only calls the handler when the Page Down key is released.
Performance consideration with .passive modifier
The .passive modifier is typically used with touch event listeners for improving performance on mobile devices. Do not use .passive and .prevent together because .passive indicates you do not intend to prevent the event's default behavior, and the browser will likely show a warning if you do so.
v-on directive for listening to DOM events
Use the v-on directive, typically shortened to the @ symbol, to listen to DOM events and run JavaScript when they're triggered. The usage is v-on:click="handler" or with the shortcut, @click="handler".
Mouse button modifiers
Use .left, .right, or .middle to restrict handlers to events triggered by a specific mouse button. These modifiers represent the main, secondary, and auxiliary pointing device event triggers respectively, not necessarily the physical buttons, so they adapt to left-handed mice, trackpads, and other pointing devices.
.exact modifier for system modifier combinations
The .exact modifier allows control of the exact combination of system modifiers needed to trigger an event. Example: @click.ctrl triggers even if Alt or Shift is pressed, but @click.ctrl.exact only triggers when Ctrl and no other keys are pressed. @click.exact only triggers when no system modifiers are pressed.
System modifier keys
Use these modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed: .ctrl, .alt, .shift, .meta. Example: <input @keyup.alt.enter="clear" /> triggers on Alt+Enter. Note: with keyup events, the modifier key must be pressed when the event is emitted.
Event modifier chaining and order matters
Event modifiers can be chained. The order matters because relevant code is generated in the same order. @click.prevent.self prevents click's default action on the element itself and its children, while @click.self.prevent only prevents click's default action on the element itself.
Dynamic select options with v-for
Select options can be dynamically rendered using v-for. Example: <select v-model="selected"><option v-for="option in options" :value="option.value">{{ option.text }}</option></select> allows options to be generated from an array of objects with text and value properties.
v-model simplifies form input binding
The v-model directive automatically syncs the state of form input elements with corresponding state in JavaScript. Instead of manually wiring up :value bindings and @input event listeners, v-model can be used as shorthand. For example, <input v-model="text"> replaces the need to write <input :value="text" @input="event => text = event.target.value">.
IME composition with v-model
For languages requiring an Input Method Editor (IME) such as Chinese, Japanese, or Korean, v-model does not update during IME composition. To respond to these updates, use a manual input event listener with value binding instead of v-model.
v-model.number modifier
The .number modifier automatically typecasts user input as a number. Example: <input v-model.number="age" /> will convert the input to a number using parseFloat(). If the value cannot be parsed as a number, the original string value is used. If the input is empty, an empty string is returned. This modifier is applied automatically if the input has type="number".
v-model.lazy modifier
By default, v-model syncs the input with data after each input event (except during IME composition). The .lazy modifier changes this to sync after change events instead. Example: <input v-model.lazy="msg" /> will update msg only when the user leaves the input field, not on every keystroke.
Select option value binding with objects
v-model supports value bindings of non-string values. Select options can bind to objects using :value. Example: <option :value="{ number: 123 }">123</option> will set the selected state to the object literal { number: 123 } when selected.
Radio button value binding
Radio buttons can bind their values to dynamic values using v-bind. Example: <input type="radio" v-model="pick" :value="first" /> will set pick to the value of the first property when selected.
true-value and false-value don't affect form submission
The true-value and false-value attributes don't affect the input's value attribute, because browsers don't include unchecked boxes in form submissions. To guarantee that one of two values is submitted in a form (e.g. 'yes' or 'no'), use radio inputs instead.
true-value and false-value for checkbox
The true-value and false-value attributes are Vue-specific and only work with v-model on checkboxes. They allow customizing the values stored when the checkbox is checked or unchecked. Example: <input type="checkbox" v-model="toggle" true-value="yes" false-value="no" /> will set toggle to 'yes' when checked and 'no' when unchecked. These attributes can also be bound to dynamic values using v-bind.
Provide disabled select option with empty value
If the initial value of a v-model expression does not match any of the select options, the select element will render in an unselected state. On iOS, this prevents users from selecting the first item because iOS does not fire a change event. It is recommended to provide a disabled option with an empty value to improve user experience: <option disabled value="">Please select one</option>.
v-model with multiple select
A select element with the multiple attribute bound with v-model will update an array state. Each selected option's value is added to the array. When options are deselected, their values are removed from the array.
v-model with single select
A select element bound with v-model will update the state to the value of the selected option. Example: <select v-model="selected"><option>A</option><option>B</option></select> will set selected to the selected option's value.
v-model with radio buttons
Radio buttons bound with v-model will update the state to the value of the selected radio button. Only one radio button in a group can be selected at a time. Example: <input type="radio" value="One" v-model="picked" /> will set picked to 'One' when selected.
v-model with multiple checkboxes
Multiple checkboxes can be bound to the same array or Set value. Each checkbox should have a value attribute. When checked, the checkbox's value is added to the array; when unchecked, it is removed. The array will always contain the values from the currently checked boxes.
v-model with single checkbox
A single checkbox bound with v-model will toggle a boolean value. Example: <input type="checkbox" v-model="checked" /> will set checked to true when the box is checked and false when unchecked.
v-model with textarea doesn't support interpolation
Interpolation inside <textarea> tags does not work. Use v-model instead. For example, use <textarea v-model="text"></textarea> instead of <textarea>{{ text }}</textarea>.
v-model with text input
For text inputs, v-model binds to the input value. Example: <input v-model="message" placeholder="edit me" /> will sync the message state with the input value as the user types.
v-model.trim modifier
The .trim modifier automatically removes whitespace from user input. Example: <input v-model.trim="msg" /> will trim leading and trailing whitespace from the input value.
v-model ignores initial HTML attributes
v-model will ignore the initial value, checked, or selected attributes found on any form elements. It always treats the current bound JavaScript state as the source of truth. The initial value should be declared on the JavaScript side, using the data option (Options API) or reactivity APIs (Composition API).
v-model uses different properties and events per element type
v-model automatically expands to different DOM property and event pairs based on the element type it is used on: <input> with text types and <textarea> elements use the value property and input event; <input type="checkbox"> and <input type="radio"> use the checked property and change event; <select> uses value as a prop and change as an event.
v-for iterating over object properties
You can use v-for to iterate through the properties of an object. The iteration order is based on Object.values(). You can provide a second alias for the property name (key) using syntax (value, key) in myObject, and a third alias for the index using (value, key, index) in myObject.
v-for scope and parent access
Inside the v-for scope, template expressions have access to all parent scope properties. Each v-for scope has access to parent scopes, similar to nested functions in JavaScript. The variable scoping matches the function signature of a forEach callback.
v-for with index and destructuring
Inside v-for, you can access an optional second alias for the index of the current item using syntax like (item, index) in items. You can also use destructuring on the v-for item alias, similar to destructuring function arguments, such as ({ message }, index) in items.
v-for directive syntax
The v-for directive renders a list of items based on an array using the syntax 'item in items', where items is the source data array and item is an alias for the current array element being iterated on. You can also use 'of' as a delimiter instead of 'in', which is closer to JavaScript iterator syntax.