Conditional and List Rendering
Vue.js Development
Conditional and List Rendering
Conditional and list rendering directives are fundamental to building dynamic interfaces in Vue. The v-if directive conditionally renders elements based on truthy values, while v-for renders lists of elements from arrays or objects. These directives work directly in your HTML templates, making it intuitive to express how your UI should look based on your component's data state. Understanding when to use v-if versus v-show, and how to use v-for efficiently with keys, is essential for building performant Vue applications.
Conditional Rendering with v-if
The v-if directive conditionally renders an element and its children. When the condition is false, the element is completely removed from the DOM — not just hidden. Use v-else-if and v-else for multiple conditions.
<template>
<div>
<!-- Simple conditional -->
<p v-if="isLoggedIn">Welcome back, {{ userName }}!</p>
<p v-else>Please log in to continue.</p>
<!-- Multiple conditions -->
<div v-if="status === 'loading'">
<p>Loading data...</p>
</div>
<div v-else-if="status === 'error'">
<p class="error">Error: {{ errorMessage }}</p>
</div>
<div v-else-if="status === 'empty'">
<p>No results found.</p>
</div>
<div v-else>
<p>Showing {{ items.length }} results.</p>
</div>
<!-- Group multiple elements with template -->
<template v-if="showDetails">
<h3>{{ product.name }}</h3>
<p>{{ product.description }}</p>
<p>Price: ${{ product.price }}</p>
</template>
</div>
</template>
v-show vs v-if
The v-show directive toggles the CSS display property instead of adding or removing elements from the DOM. Use v-show for elements that toggle frequently and v-if for conditions that rarely change.
<template>
<div>
<!-- v-show: element stays in DOM, display is toggled -->
<div v-show="isVisible" class="panel">
This panel toggles with CSS display property.
</div>
<!-- v-if: element is added/removed from DOM -->
<div v-if="isVisible" class="panel">
This panel is completely removed when hidden.
</div>
<button @click="isVisible = !isVisible">Toggle Panel</button>
<!-- v-show does NOT work on template elements -->
<!-- <template v-show="condition"> DOES NOT WORK </template> -->
</div>
</template>
List Rendering with v-for
The v-for directive renders a list of elements based on an array or object. Always provide a unique :key attribute to help Vue's virtual DOM efficiently track and update list items.
<template>
<div>
<!-- Array iteration with index -->
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index + 1 }}. {{ item.name }} — ${{ item.price.toFixed(2) }}
<button @click="removeItem(index)">Remove</button>
</li>
</ul>
<!-- Object iteration -->
<div v-for="(value, key) in userProfile" :key="key">
<strong>{{ key }}:</strong> {{ value }}
</div>
<!-- Range — renders 1 through 10 -->
<span v-for="n in 10" :key="n">{{ n }} </span>
<!-- v-for on template for multiple root elements -->
<template v-for="item in items" :key="item.id">
<h3>{{ item.name }}</h3>
<p>{{ item.description }}</p>
<hr />
</template>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: "Laptop", price: 999.99, description: "Powerful laptop" },
{ id: 2, name: "Mouse", price: 29.99, description: "Wireless mouse" },
{ id: 3, name: "Keyboard", price: 79.99, description: "Mechanical keyboard" },
],
userProfile: {
name: "Alice",
email: "alice@test.com",
role: "Admin",
},
};
},
methods: {
removeItem(index) {
this.items.splice(index, 1);
},
},
};
</script>
Tip: Never usev-ifandv-foron the same element. When they coexist,v-ifhas higher priority in Vue 3 and cannot access thev-forvariable. Instead, filter the list in a computed property or wrap thev-ifin a<template>element.
Key Takeaways
v-ifconditionally adds or removes elements from the DOM; supportsv-else-ifandv-else.v-showtoggles CSS display and is better for frequently toggled elements.v-forrenders lists from arrays, objects, or ranges with(item, index) in arraysyntax.- Always provide a unique
:keyattribute withv-forfor efficient DOM updates. - Avoid using
v-ifandv-foron the same element — use computed properties or<template>instead.