Что делает директива v-for?

Во Vue.js директива v-for используется для рендеринга списков на основе данных. Она позволяет перебрать массив, объект или диапазон чисел и отобразить DOM-элементы для каждого элемента этого списка. Это один из самых мощных инструментов Vue для динамического построения контента, основанного на структуре данных.

Основной синтаксис

<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>

Здесь items — это массив из data(), а item — текущий элемент в итерации. Ключ (:key) обязателен при рендеринге списков для обеспечения правильного отслеживания элементов Vue при обновлениях.

Пример базового использования

data() {
return {
fruits: \['яблоко', 'банан', 'груша'\]
}
}
<ul>
<li v-for="fruit in fruits" :key="fruit">{{ fruit }}</li>
</ul>

Vue сгенерирует:

<ul>
<li>яблоко</li>
<li>банан</li>
<li>груша</li>
</ul>

С указанием индекса

Vue позволяет получать и индекс текущего элемента:

<li v-for="(fruit, index) in fruits" :key="index">
{{ index }}: {{ fruit }}
</li>

Это выведет:

0: яблоко

1: банан

2: груша

Однако использовать индекс в качестве key не рекомендуется, если список может изменяться (добавление/удаление/перестановка элементов). Лучше использовать уникальные ID.

v-for с объектом

Vue может перебирать не только массивы, но и объекты:

data() {
return {
user: {
name: 'Иван',
age: 30,
city: 'Ташкент'
}
}
}
<ul>
<li v-for="(value, key) in user" :key="key">
{{ key }}: {{ value }}
</li>
</ul>

Вывод:

name: Иван
age: 30
city: Ташкент

v-for с диапазоном чисел

<div v-for="n in 5" :key="n">
{{ n }}
</div>

Выведет:

1

2

3

4

5

То есть v-for="n in 5" означает повторить 5 раз с n от 1 до 5.

Вложенные циклы

v-for можно вкладывать:

data() {
return {
categories: \[
{
name: 'Фрукты',
items: \['Яблоко', 'Груша'\]
},
{
name: 'Овощи',
items: \['Морковь', 'Огурец'\]
}
\]
}
}
<div v-for="category in categories" :key="category.name">
<h3>{{ category.name }}</h3>
<ul>
<li v-for="item in category.items" :key="item">{{ item }}</li>
</ul>
</div>

Обязательное использование key

Атрибут key критически важен для оптимизации производительности и корректной работы виртуального DOM. Он позволяет Vue отслеживать элементы между рендерами и минимизировать изменения DOM. Без key, особенно при добавлении/удалении элементов, могут возникать ошибки UI или неправильное поведение.

Правильно:

<li v-for="item in items" :key="item.id">{{ item.name }}</li>

Неправильно:

<li v-for="item in items">{{ item.name }}</li>

Использование с компонентами

Когда v-for используется с компонентами, он позволяет рендерить несколько экземпляров компонента:

<user-card v-for="user in users" :key="user.id" :user="user" />

Вложенное использование с v-if

Когда нужно одновременно использовать v-for и v-if, рекомендуется разносить их по разным элементам, чтобы избежать неоднозначности в логике рендеринга:

Неправильно:

<li v-for="user in users" v-if="user.active">{{ user.name }}</li>

Правильно:

<template v-for="user in users" :key="user.id">
<li v-if="user.active">{{ user.name }}</li>
</template>

Рендеринг на лету

Можно создавать списки динамически:

<input v-model.number="count" type="number" />
<ul>
<li v-for="n in count" :key="n">Элемент {{ n }}</li>
</ul>

Когда пользователь меняет число в поле, список мгновенно перестраивается.

Итерация с template

Когда нужен обёртка без лишнего DOM-элемента:

<template v-for="item in items" :key="item.id">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</template>

<template> не отображается в DOM, но позволяет использовать v-for без лишнего div или li.

Особенности

  • v-for работает в реактивной системе Vue — любые изменения массива или объекта (добавление, удаление, изменение) автоматически обновляют DOM.

  • Методы вроде push, splice, pop, shift, unshift, sort, reverse также отслеживаются Vue и вызывают перерендер.

  • При использовании v-for с компонентами важно понимать, что каждый экземпляр компонента будет иметь собственный жизненный цикл.

Директива v-for — это мощный способ создавать повторяющиеся DOM-структуры на основе реактивных данных. Она поддерживает разные источники данных (массивы, объекты, числа) и хорошо сочетается с остальной реактивной системой Vue.