Vue List Rendering: Why `key` is Not Optional
Think of `key` as a license plate for each item in a list. Without it, Vue just repaints items in order. With `key`, Vue tracks and preserves each item's state across re-renders. This is vital for dynamic lists with stateful components, like form inputs.
WHY IT EXISTS: When a list of data changes, Vue needs an efficient way to update the corresponding list of DOM elements. Instead of rebuilding the entire list from scratch, it tries to reuse as many existing elements as possible. The key attribute solves the problem of knowing which old DOM element corresponds to which new data item, especially when the list is reordered.
THE MENTAL MODEL: Imagine a classroom of students. Without a key, Vue identifies students by their seat position. If the first two students swap seats, Vue thinks they are new people and just repaints their names. With a key (like a unique student ID), Vue knows exactly who is who, no matter where they sit. It can simply move the existing students (and their backpacks full of state) to their new seats, which is far more efficient and less error-prone.
HOW IT WORKS: By default, without key, Vue uses an "in-place patch" strategy. It iterates through the new and old lists simultaneously and patches the element at each position. This is fast but can lead to state mismatches. When you provide a unique key for each item, Vue uses it to build a map of old nodes. When the list updates, it uses this map to see if an item with the same key still exists. If so, it reuses and moves the old DOM node. If not, it creates a new one. This ensures state is preserved with its corresponding data item.
WHEN TO USE IT: You should always provide a key when using v-for, unless the list is simple, static, and will never be reordered. It is absolutely critical when list items have their own internal state (like form inputs), when you are applying transitions to the list, or when the list's order can change through sorting, filtering, or splicing.
WHEN NOT TO USE IT: The primary footgun is using the array index as the key (:key="index"). This seems convenient but defeats the purpose of key. If an item is added to the beginning of the array, all indices shift, and Vue will incorrectly reuse nodes, leading to the very state management bugs key is meant to prevent. Always use a stable, unique ID from the data item itself (e.g., item.id).
ONE CANONICAL EXAMPLE: Consider a to-do list where each item has an <input> checkbox. If you render this list using :key="index" and then delete the first to-do item, the list will re-render incorrectly. The text of the items will update, but the checked status of the checkboxes will not. The second item's text will move to the first position, but it will inherit the checked state of the original first item. Using a unique todo.id as the key ensures that when an item is deleted, its entire DOM node (including its checkbox state) is removed, and all other items remain untouched.
Read the original → vuejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.