Списки: v-for и key
Выводим списки данных в разметку через директиву v-for и разбираемся, почему атрибут key — не формальность, а важная вещь для производительности.
v-for — директива, которая повторяет элемент шаблона для каждого элемента массива или каждого свойства объекта.
Перебор массива
Синтаксис v-for="item in items" создаёт по одному элементу на каждый item. К каждому элементу нужно добавить уникальный :key:
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const users = ref([
{ id: 1, name: 'Аня' },
{ id: 2, name: 'Борис' },
{ id: 3, name: 'Вера' },
])
</script>
Доступ к индексу
Вторым параметром v-for отдаёт индекс элемента:
<template>
<ol>
<li v-for="(user, index) in users" :key="user.id">
{{ index + 1 }}. {{ user.name }}
</li>
</ol>
</template>
Зачем нужен key
Когда список меняется (добавили, удалили, переставили элемент), Vue нужно понять, какой DOM-узел какому данному соответствует. Атрибут key — это стабильный идентификатор каждого элемента. По нему Vue точно знает: «это тот же элемент, что был, просто сдвинулся» — и переиспользует существующий узел вместо пересоздания.
Без key (или с индексом массива в роли ключа) Vue сопоставляет элементы по позиции. При вставке в начало списка это приводит к лишним обновлениям, а в формах — к багам: введённый текст «перескакивает» не на ту строку. Поэтому в ключ ставьте стабильный уникальный id из данных, а не индекс.
Проверим логику ключей на JS
Уникальность id легко прочувствовать обычным кодом. Сделаем «ключи» из массива объектов и убедимся, что они уникальны:
const users = [
{ id: 101, name: "Аня" },
{ id: 102, name: "Борис" },
{ id: 103, name: "Вера" },
];
const keys = users.map(u => u.id);
console.log("Ключи:", keys);
console.log("Все уникальны:", new Set(keys).size === keys.length);
Вывод:
Ключи: [ 101, 102, 103 ] Все уникальны: true
Частые ошибки
| Ошибка | Почему плохо |
Нет :key | Vue ругается в консоли, возможны баги при изменении списка |
:key="index" | при вставке/удалении ключи «съезжают», ломая привязку |
Изменение длины массива через arr[5] = x | лучше использовать push, splice — они реактивны |
Итог
v-for="item in items"повторяет элемент для каждого элемента массива.- Вторым параметром доступен индекс:
(item, index). :keyобязателен — это стабильный id для эффективного обновления DOM.- В ключ ставьте уникальный id из данных, а не индекс массива.