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.

Notes

The rule walks the <template> block of .vue Single-File Components and reports each element that has a v-for attribute but neither :key nor v-bind:key. Any other v--prefixed key form (such as v-bind:key.sync) also satisfies the rule.