How to use v-if with v-for in Vue
Combining conditional rendering with list rendering is a common need in Vue applications, but using v-if and v-for on the same element can cause performance and priority issues. As the creator of CoreUI, a widely used open-source UI library with Vue support, I’ve handled conditional list rendering countless times. The most efficient approach is using computed properties to filter data before rendering, or wrapping the v-for element with a template that has v-if. This method avoids directive conflicts and improves performance.
Use a computed property to filter items before iterating with v-for.
export default {
setup() {
const items = ref([
{ id: 1, name: 'Item 1', active: true },
{ id: 2, name: 'Item 2', active: false },
{ id: 3, name: 'Item 3', active: true }
])
const activeItems = computed(() =>
items.value.filter(item => item.active)
)
return { activeItems }
},
template: `
<div v-for="item in activeItems" :key="item.id">
{{ item.name }}
</div>
`
}
Here a computed property filters the items array before rendering. This approach evaluates the condition once per item during filtering rather than on every render cycle. The v-for directive only iterates over the filtered result, avoiding the performance overhead and priority conflicts that occur when v-if and v-for coexist on the same element.
Best Practice Note:
This is the pattern we use in CoreUI Vue components to handle conditional list rendering efficiently. Avoid placing v-if and v-for on the same element, as Vue 3 gives v-if higher priority, which can lead to unexpected behavior when the v-if references variables from the v-for scope.



