Skip to main content

Vue.js v-if Directive

Conditional rendering is a fundamental concept in building interactive web applications. Vue.js provides a powerful directive called v-if that allows you to show or hide elements in the DOM based on the truthiness of an expression.

Introduction

The v-if directive in Vue.js is used to conditionally render a block of content. The block will only be rendered if the directive's expression returns a truthy value. This is one of the most commonly used directives in Vue applications and is essential for building dynamic user interfaces.

Basic Syntax

The basic syntax of the v-if directive is as follows:

html
<element v-if="condition">
<!-- content here will only render if condition is truthy -->
</element>

Where condition is a JavaScript expression that evaluates to either true or false.

How v-if Works

When Vue encounters an element with the v-if directive, it evaluates the provided expression. If the expression is truthy, the element is rendered in the DOM. If the expression is falsy, the element is completely removed from the DOM (not just hidden).

Truthy and Falsy Values in JavaScript

Before diving deeper, let's understand what truthy and falsy values are in JavaScript:

Falsy values:

  • false
  • 0
  • "" (empty string)
  • null
  • undefined
  • NaN

Truthy values:

  • Everything else not in the falsy list

Basic Example

Let's look at a simple example:

html
<template>
<div>
<button @click="toggleShow">Toggle Content</button>

<h2 v-if="isShown">This content is visible!</h2>
</div>
</template>

<script>
export default {
data() {
return {
isShown: true
}
},
methods: {
toggleShow() {
this.isShown = !this.isShown
}
}
}
</script>

In this example:

  1. We have a data property isShown initially set to true.
  2. The h2 element will be rendered because isShown is true.
  3. When the button is clicked, the toggleShow method is called, which inverts the value of isShown.
  4. If isShown becomes false, the h2 element will be removed from the DOM.

Using v-else and v-else-if

Vue.js provides v-else and v-else-if directives that work together with v-if to create more complex conditional rendering scenarios.

v-else

The v-else directive can be used to define an "else block" for a v-if:

html
<div v-if="isAuthenticated">
Welcome back, User!
</div>
<div v-else>
Please log in to continue.
</div>

v-else-if

The v-else-if directive serves as an "else if block" for v-if, allowing for multiple conditions:

html
<div v-if="type === 'A'">
Type A
</div>
<div v-else-if="type === 'B'">
Type B
</div>
<div v-else-if="type === 'C'">
Type C
</div>
<div v-else>
Not A, B, or C
</div>
caution

An element with v-else or v-else-if must immediately follow an element with v-if or v-else-if. Otherwise, it won't be recognized.

Complete Example with v-if, v-else-if, and v-else

Here's a more complete example showing a user's subscription status:

html
<template>
<div>
<h2>User Subscription Status</h2>

<div class="card">
<div v-if="subscriptionStatus === 'premium'">
<h3>Premium Subscription</h3>
<p>Thank you for being a premium subscriber! Enjoy all our features.</p>
</div>
<div v-else-if="subscriptionStatus === 'basic'">
<h3>Basic Subscription</h3>
<p>You have access to basic features. Consider upgrading to premium!</p>
</div>
<div v-else-if="subscriptionStatus === 'trial'">
<h3>Trial Subscription</h3>
<p>Your trial ends in {{ trialDaysLeft }} days. Subscribe to continue access.</p>
</div>
<div v-else>
<h3>No Subscription</h3>
<p>Explore our subscription options to get started!</p>
</div>
</div>

<div class="controls">
<button @click="setSubscription('premium')">Set Premium</button>
<button @click="setSubscription('basic')">Set Basic</button>
<button @click="setSubscription('trial')">Set Trial</button>
<button @click="setSubscription('none')">Set None</button>
</div>
</div>
</template>

<script>
export default {
data() {
return {
subscriptionStatus: 'none',
trialDaysLeft: 7
}
},
methods: {
setSubscription(type) {
this.subscriptionStatus = type
}
}
}
</script>

Conditional Groups with Template Tag

If you want to toggle multiple elements together without adding an extra wrapper div to your DOM, you can use the <template> tag with v-if:

html
<template>
<div>
<template v-if="showContent">
<h2>Title</h2>
<p>This paragraph is part of the same conditional block.</p>
<small>This will appear and disappear together with the above elements.</small>
</template>

<button @click="showContent = !showContent">Toggle Content</button>
</div>
</template>

<script>
export default {
data() {
return {
showContent: true
}
}
}
</script>

The <template> tag acts as an invisible wrapper that won't be rendered in the final HTML.

v-if vs v-show

Vue.js offers another directive called v-show which appears similar to v-if but has important differences:

  • v-if completely adds or removes elements from the DOM
  • v-show simply toggles the CSS display property
html
<!-- v-if: Element is completely added/removed from DOM -->
<div v-if="isVisible">This uses v-if</div>

<!-- v-show: Element is always in the DOM, but has display:none when false -->
<div v-show="isVisible">This uses v-show</div>

When to use v-if vs v-show

  • Use v-if when the condition doesn't change frequently or when you need to control whether components are initialized
  • Use v-show for elements that toggle visibility very frequently (since toggling CSS is less expensive than adding/removing from DOM)

Real-World Application: Form Validation

Here's a practical example showing how v-if can be used for form validation:

html
<template>
<div class="form-container">
<h2>Registration Form</h2>
<form @submit.prevent="submitForm">
<div class="form-field">
<label for="email">Email:</label>
<input
type="email"
id="email"
v-model="email"
@blur="validateEmail"
/>
<div v-if="errors.email" class="error-message">
{{ errors.email }}
</div>
</div>

<div class="form-field">
<label for="password">Password:</label>
<input
type="password"
id="password"
v-model="password"
@blur="validatePassword"
/>
<div v-if="errors.password" class="error-message">
{{ errors.password }}
</div>
</div>

<div v-if="formSubmitted && !formValid" class="form-error">
Please fix the errors before submitting.
</div>

<button type="submit">Register</button>
</form>
</div>
</template>

<script>
export default {
data() {
return {
email: '',
password: '',
errors: {
email: '',
password: ''
},
formSubmitted: false
}
},
computed: {
formValid() {
return !this.errors.email && !this.errors.password && this.email && this.password
}
},
methods: {
validateEmail() {
if (!this.email) {
this.errors.email = 'Email is required'
} else if (!this.email.includes('@')) {
this.errors.email = 'Please enter a valid email address'
} else {
this.errors.email = ''
}
},
validatePassword() {
if (!this.password) {
this.errors.password = 'Password is required'
} else if (this.password.length < 8) {
this.errors.password = 'Password must be at least 8 characters'
} else {
this.errors.password = ''
}
},
submitForm() {
this.formSubmitted = true
this.validateEmail()
this.validatePassword()

if (this.formValid) {
// Form submission logic would go here
alert('Form submitted successfully!')
}
}
}
}
</script>

<style scoped>
.error-message {
color: red;
font-size: 0.8rem;
margin-top: 5px;
}
.form-error {
color: red;
margin: 10px 0;
}
</style>

In this form validation example:

  1. Error messages appear conditionally using v-if when validation fails
  2. A form-level error message appears only if the form was submitted and has validation errors
  3. The validation occurs when inputs lose focus (@blur) and on form submission

Performance Considerations

When using v-if for conditional rendering, there are some performance considerations to keep in mind:

  1. Initial rendering cost: v-if has a higher initial rendering cost if the condition changes from false to true, as Vue needs to render the entire element and its children.

  2. Toggle frequency: If you need to toggle visibility very frequently, consider using v-show instead of v-if.

  3. Component initialization: When using v-if with components, the component isn't initialized until the condition becomes true, and it's destroyed when the condition becomes false. This can be advantageous for performance but might cause issues if you need to preserve component state.

Common Mistakes

Confusing v-if with v-show

html
<!-- This completely removes the element from DOM when isVisible is false -->
<div v-if="isVisible">Content</div>

<!-- This just hides the element with CSS when isVisible is false -->
<div v-show="isVisible">Content</div>

Incorrect v-else placement

The v-else directive must immediately follow an element with v-if or v-else-if:

html
<!-- This works -->
<div v-if="condition">A</div>
<div v-else>B</div>

<!-- This doesn't work because there's an element in between -->
<div v-if="condition">A</div>
<p>Something else</p>
<div v-else>B</div> <!-- This v-else will not be recognized -->

Summary

The v-if directive in Vue.js is a powerful tool for conditional rendering:

  • It completely adds or removes elements from the DOM based on the truthiness of an expression
  • Works together with v-else and v-else-if for complex conditional logic
  • Can be used with the <template> tag to toggle multiple elements without adding extra DOM nodes
  • Differs from v-show which only toggles visibility using CSS
  • Is useful in many practical scenarios like user interfaces, form validation, and permission-based content display

By mastering the v-if directive, you'll be able to create more dynamic and interactive Vue.js applications that respond to user input and application state changes.

Exercises

To reinforce your understanding of the v-if directive, try these exercises:

  1. Create a simple login/logout toggle that shows different content based on whether a user is logged in.

  2. Build a multi-step form where each step is shown conditionally based on the current step number.

  3. Create a weather app interface that shows different UI elements based on the weather conditions (sunny, rainy, cloudy, etc.).

  4. Implement a permission-based dashboard where different UI components are shown based on user roles (admin, editor, viewer, etc.).

Additional Resources

Happy coding with Vue.js!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)