Коли список змінюється, Vue порівнює старий і новий віртуальний DOM і намагається перевикористати наявні елементи. key каже, який новий елемент відповідає якому старому.
<TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" />
Без key або з індексом Vue зіставляє елементи за позицією. Поки список лише дописують у кінець, усе гаразд. Але після видалення, вставки на початок чи сортування:
- елемент на позиції 0 тепер показує інші дані, але його внутрішній стан лишився від попереднього: введений в
<input>текст, розгорнутий блок, локальний стан дочірнього компонента, фокус; - анімації
<TransitionGroup>рухають не ті елементи; - Vue оновлює вміст кожного зсунутого елемента замість того, щоб просто перемістити один.
// Видалили перший елемент: індекси зсунулися,
// і стан TodoItem[0] тепер «належить» колишньому другому
todos.value.splice(0, 1);
Хороший key - стабільний і унікальний серед сусідів: id з бази, стабільний ідентифікатор. Погані: індекс (для списків, що змінюються), Math.random() (новий щоразу - Vue перестворюватиме всі елементи на кожен рендер).
Індекс допустимий, коли список статичний або елементи не мають власного стану й не змінюють порядок.
Корисний прийом: зміна key на одному компоненті примусово його перестворює - простий спосіб «скинути» компонент: <UserForm :key="userId" />.