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>