List Rendering v-for
In modern web development, rendering dynamic collections of data efficiently is a daily requirement. Within the Vue ecosystem, the v-for directive serves as the primary tool for list rendering, allowing developers to generate groups of elements seamlessly based on arrays, objects, or even integer ranges. Mastering its various patterns lays a solid foundation for building responsive and interactive user interfaces.
The fundamental syntax of v-for relies on the item in items expression, where items points to the source data array and item acts as an alias for the element currently being iterated over.
<template>
<ul>
<li v-for="item in fruits" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const fruits = ref([
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Orange' }
])
</script>
When you need to track the position of each item within the collection, you can extend the alias syntax to include an index: (item, index) in items.
<li v-for="(item, index) in fruits" :key="item.id">
{{ index + 1 }}. {{ item.name }}
</li>
Beyond arrays, v-for can also iterate over the properties of an object. In this context, you can accept additional arguments to capture both the property value, the key name, and an optional iteration index: (value, key, index).
<ul>
<li v-for="(value, key, index) in userInfo" :key="key">
{{ index }}: {{ key }} = {{ value }}
</li>
</ul>
const userInfo = ref({
name: 'John Doe',
age: 28,
city: 'Seattle'
})
Working with Integer Ranges
The directive also accepts integer values directly. When a number n is provided, v-for will execute a loop where the alias starts counting upward from 1 through n.
<span v-for="n in 5" :key="n">{{ n }} </span>
<!-- Renders: 1 2 3 4 5 -->
The Significance of the key Attribute
A crucial best practice when using v-for is supplying a unique and stable key attribute for every rendered node. The key provides a hint to Vue's virtual DOM diffing algorithm, enabling it to accurately identify individual nodes and efficiently reuse or patch existing elements rather than tearing down and recreating the entire list.
- Always use unique, stable identifiers from your data source, such as a database
id. - Avoid using array indices as keys—especially if your application permits sorting, insertions, or deletions—as doing so can lead to subtle rendering bugs and performance degradation.
Array Mutation Detection
Vue keeps track of reactive arrays by wrapping standard array methods. Invoking any of these mutation methods on a source array will automatically trigger UI updates:
- Mutation methods (which modify the original array):
push(),pop(),shift(),unshift(),splice(),sort(), andreverse(). - Non-mutating methods (which return a new array):
filter(),concat(), andslice().
When working with non-mutating methods, you must explicitly replace the old array reference with the newly returned array to ensure the view updates correctly:
// Correct: Reassigning the array reference with the filtered result
fruits.value = fruits.value.filter(item => item.id !== 2)
Combining v-for and v-if
In Vue 3, v-if carries a higher evaluation priority than v-for. Consequently, placing both directives on the same root element is strongly discouraged. If you need to conditionally filter items in a list, you should preprocess the source collection using a computed property instead:
const ripeFruits = computed(() =>
fruits.value.filter(item => item.ripe)
)
<li v-for="item in ripeFruits" :key="item.id">{{ item.name }}</li>
This approach keeps templates clean, separates business logic from presentation, and avoids unnecessary evaluation overhead on every render cycle.
Nested List Rendering
Because v-for directives can be nested within one another, they are well-suited for displaying multi-level hierarchical structures, such as product categories and their corresponding sub-items:
<ul>
<li v-for="category in categories" :key="category.id">
{{ category.name }}
<ul>
<li v-for="product in category.products" :key="product.id">
{{ product.name }}
</li>
</ul>
</li>
</ul>
Summary
The v-for directive is an indispensable pillar of template authoring in Vue. Keeping a few key principles in mind will ensure your applications remain performant and maintainable:
- Always bind a unique and stable
keyto every rendered item. - Leverage extended parameter signatures when iterating over objects, and remember that integer loops begin at
1. - Never mix
v-forandv-ifon the same element; rely on computed properties for filtering instead. - When utilizing non-mutating array methods, remember to update the underlying reference.
Applying these techniques consistently will lead to robust, high-performance list rendering throughout your codebase.