Vue v-for Missing :key
ID |
javascript.vue_for_without_key |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Reliability |
Language |
JavaScript |
Tags |
framework, reliability, vue |
Description
Reports a Vue template element that uses v-for without a :key (or v-bind:key) binding:
<!-- Bad — no :key -->
<li v-for="item in items">{{ item }}</li>
<!-- Good -->
<li v-for="item in items" :key="item.id">{{ item }}</li>
Rationale
Vue uses the key attribute to track each rendered child between updates. Without :key, Vue falls back to an "in-place patch" strategy that:
-
mishandles list reordering — child components stay attached to the wrong item,
-
loses local state in child components when items are inserted or removed in the middle of the list,
-
causes flickering on stable lists that should not have re-rendered.
The Vue style guide marks this as an "essential" rule (priority A): v-for without :key is one of the most common sources of "weird UI" bugs in Vue applications.
Remediation
Bind :key to a stable, unique identifier for each item:
<li v-for="item in items" :key="item.id">{{ item }}</li>
<!-- For primitive-only lists where each value is itself unique: -->
<li v-for="value in uniqueValues" :key="value">{{ value }}</li>
If no natural key exists, derive one (e.g. compose multiple fields). Avoid using the array index as :key unless the list is truly static — index keys reintroduce the same in-place patch problem.