v-memo with v-for for large lists
v-memo is useful with v-for when rendering large lists (length > 1000). When using v-memo with v-for, ensure they are used on the same element; v-memo does not work inside v-for. Example: <div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">. This allows unaffected items to reuse their previous VNode and skip diffing. You do not need to include the keyed value in the memo dependency array since Vue automatically infers it from the item's :key.
v-for directive syntax and usage
v-for renders an element or template block multiple times based on source data. It expects Array, Object, number, string, or Iterable values. The directive's value must use the special syntax 'alias in expression' to provide an alias for the current element. You can specify an alias for the index: (item, index) in items. For objects, you can use (value, key) in object or (value, name, index) in object. The default behavior attempts to patch elements in-place. Use the key special attribute to provide an ordering hint: <div v-for="item in items" :key="item.id">. v-for works on values implementing the Iterable Protocol, including native Map and Set.
v-for directive syntax with item in items
The v-for directive uses the syntax `item in items` where items is the source data array and item is an alias for the array element being iterated on.
v-for scope access to parent properties
Inside the v-for scope, template expressions have access to all parent scope properties.
v-for with index alias syntax
v-for supports an optional second alias for the index of the current item using the syntax `(item, index) in items`.
v-for with destructuring
You can use destructuring on the v-for item alias similar to destructuring function arguments. For example: `<li v-for="{ message } in items">{{ message }}</li>` or with index: `<li v-for="({ message }, index) in items">{{ message }} {{ index }}</li>`
v-for with nested scoping
For nested v-for, scoping works similar to nested functions. Each v-for scope has access to parent scopes. For example: `<li v-for="item in items"><span v-for="childItem in item.children">{{ item.message }} {{ childItem }}</span></li>`
v-for with of delimiter instead of in
You can use `of` as the delimiter instead of `in` in v-for to be closer to JavaScript's syntax for iterators. For example: `<div v-for="item of items"></div>`
v-for with object iteration
You can use v-for to iterate through the properties of an object. The iteration order will be based on the result of calling Object.values() on the object.
v-for object with value, key, and index aliases
When iterating an object with v-for, you can provide: a value alias `(value in myObject)`, a key alias `(value, key in myObject)`, and an index alias `(value, key, index in myObject)`.
v-for with integer range
v-for can take an integer and will repeat the template that many times based on a range of 1...n. For example: `<span v-for="n in 10">{{ n }}</span>`. The variable n starts with an initial value of 1 instead of 0.
v-for on template tag
Similar to template v-if, you can use a <template> tag with v-for to render a block of multiple elements without adding a wrapper element.
v-for with v-if priority and scoping
When v-if and v-for exist on the same node, v-if has a higher priority than v-for. This means the v-if condition will not have access to variables from the scope of the v-for. This is problematic and not recommended.
Fix v-for with v-if by moving v-for to template
To fix v-if and v-for on the same element, move v-for to a wrapping <template> tag. For example: `<template v-for="todo in todos"><li v-if="!todo.isComplete">{{ todo.name }}</li></template>`
v-if and v-for best practices
To filter items in a list, replace the array with a new computed property that returns your filtered list. To avoid rendering a list if it should be hidden, move the v-if to a container element like ul or ol.
v-for key attribute purpose
The key attribute provides a unique identifier for each item in a v-for list. It gives Vue a hint to track each node's identity, allowing Vue to reuse and reorder existing elements instead of using the default in-place patch strategy.
v-for key binding syntax
Provide a unique key attribute for each item using the syntax: `<div v-for="item in items" :key="item.id"><!-- content --></div>`
v-for key on template tag placement
When using <template v-for>, the key should be placed on the <template> container, not on child elements. For example: `<template v-for="todo in todos" :key="todo.name"><li>{{ todo.name }}</li></template>`
v-for key binding expects primitive values
The key binding expects primitive values - strings and numbers. Do not use objects as v-for keys.
When to provide v-for key attribute
It is recommended to provide a key attribute with v-for whenever possible, unless the iterated DOM content is simple (contains no components or stateful DOM elements), or you are intentionally relying on the default behavior for performance gains.
v-for on component with key
You can directly use v-for on a component like any normal element. For example: `<MyComponent v-for="item in items" :key="item.id" />`
v-for on component requires explicit props
Using v-for on a component won't automatically pass any data to the component because components have isolated scopes. You must explicitly pass data to the component using props. For example: `<MyComponent v-for="(item, index) in items" :item="item" :index="index" :key="item.id" />`
Array replacement is efficient in Vue
Replacing an array with another array containing overlapping objects is a very efficient operation. Vue implements smart heuristics to maximize DOM element reuse, so it won't throw away the existing DOM and re-render the entire list.
Displaying filtered or sorted results with computed property
To display a filtered or sorted version of an array without mutating the original data, create a computed property that returns the filtered or sorted array. For composition API: `const evenNumbers = computed(() => { return numbers.value.filter((n) => n % 2 === 0) })`. For options API: `computed: { evenNumbers() { return this.numbers.filter(n => n % 2 === 0) } }`
Using methods for filtered/sorted results in nested v-for
In situations where computed properties are not feasible (e.g. inside nested v-for loops), you can use a method to filter or sort. For composition API: `function even(numbers) { return numbers.filter((number) => number % 2 === 0) }`. For options API: `methods: { even(numbers) { return numbers.filter(number => number % 2 === 0) } }`
Array mutation methods detected by Vue
Vue can detect when a reactive array's mutation methods are called and trigger necessary updates. These methods are: push(), pop(), shift(), unshift(), splice(), sort(), reverse().
Avoid mutating arrays in computed properties
Be careful with reverse() and sort() in a computed property. These methods will mutate the original array, which should be avoided in computed getters. Create a copy of the original array before calling these methods. For example: `return [...numbers].reverse()` instead of `return numbers.reverse()`
Replacing array with non-mutating methods
Non-mutating methods like filter(), concat(), and slice() do not mutate the original array but return a new array. When working with non-mutating methods, replace the old array with the new one. For composition API: `items.value = items.value.filter((item) => item.message.match(/Foo/))`. For options API: `this.items = this.items.filter((item) => item.message.match(/Foo/))`