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 over my 11 years of Vue development. 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.



