Vue v-if Combined With v-for

ID

javascript.vue_if_with_for

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

framework, reliability, vue

Description

Reports a Vue template element that has both v-for and v-if directives on the same tag:

<!-- Bad — both directives on the same element -->
<li v-for="user in users" v-if="user.isActive">{{ user.name }}</li>

Rationale

Vue 2 evaluates v-for before v-if (so v-if filters each iteration), while Vue 3 evaluates v-if before v-for (so v-if references inside the directive cannot see the loop variable). Code written for one version often misbehaves under the other, and even within a single version every reader has to remember the precedence rule.

The official Vue style guide marks this as a priority A "essential" rule on both major versions.

Remediation

Pick one of the following:

  • Filter in a computed property and iterate the filtered result:

computed: {
  activeUsers() { return this.users.filter(u => u.isActive); }
}
<li v-for="user in activeUsers" :key="user.id">{{ user.name }}</li>
  • Wrap the loop in a <template v-if> block, or vice versa:

<template v-if="users.length">
  <li v-for="user in users" :key="user.id">{{ user.name }}</li>
</template>

Notes

The rule fires when both v-for and v-if are direct attributes of the same element. It does not look at v-if on a parent or child — the surprising precedence interaction only happens when the two directives share an element.