DEV Community

Mr_SC
Mr_SC

Posted on • Originally published at zelig880.com

What is the difference between v-show and v-if in Vue js

Vue Js offers us a number of directives that are based to improve the development experience. If you are new to Vue Js, you may be asking yourself, what are directives in Vue js?

Directives are special HTML attributes that enhance the developer experience by providing a set of functionality to a specific HTML element and its children. These attributes can either be build-in or custom build. All vue directives are prefixed with “v-” to make them unique.

Zelig880

Show or hide an element

If you are reading this post, big chances are that you have been trying to hide/show a specific component or element and started to encounter some difficulties or have some questions. This post will hopefully include the answers you need. If it does not, please post a comment so that I can expand it to include more information for future readers.

Currently, Vue js comes with 2 different directives that can be used to hide and show a specific component or HTLM element, v-show and v-if.

// Example of v-if
<template>
  <main>
    <h2 v-if="showHeading" >This is my heading</h2>
    The rest of the component....
  </main>
</template>

// Example of v-show
<template>
  <main>
    <h2 v-show="showHeading" >This is my heading</h2>
    The rest of the component....
  </main>
</template>

Enter fullscreen mode Exit fullscreen mode

For new users (and sometimes also advanced ones) these directives seem to be the same as they both achieve the same result of handling the visibility of the specified element, but behind the scene, these are actually different. This difference can actually turn into unwanted bugs or side effects.

What is the technical difference between v-show and v-if

These two directives are extremely different behind the scene, even if they offer the same end result.

The main difference exhibited by these directives when inactive (when the value passed to it is false) is that v-show actually renders the component or element within the DOM and applies it css declaration of display: none while v-if excluding the component of the element completely from the rendering of the component.

We are going to analyse these differences with a real example. If you would like to see the code yourself you can follow this link to the Vue SFC playground.

Let’s write a simple example that should not show any of the elements on screen:

<script setup>
import { ref } from 'vue'

const showElement = ref(false)
</script>

<template>
  <div v-if="showElement">Example of v-if</div>
  <div v-show="showElement">Example of v-show</div>
</template>
Enter fullscreen mode Exit fullscreen mode

The above code produces a completely empty canvas, but the HTML hides some hidden surprises:

<div id="app" data-v-app="">
  <!--v-if-->
  <div style="display: none;">Example of v-show</div>
</div>
Enter fullscreen mode Exit fullscreen mode

As the HTML above shows, the HTML tag created with v-show is actually included in the DOM but hidden using CSS while the one declared with v-if has been completely removed and it is just recognizable by the \<!--v-if--> comment left by the Vue compiler.

Why does it matter?

Even if the difference to our eye is inexistent, the actual difference in technology and computing terms is massive. Knowing when to use them is very important as they both share important advantages and disadvantages. Using v-if would reduce the JS required to render the page as the HTML or component (and all its children if it has any) will not be loaded at all while using v-show maybe more costly at first (as all resources are loaded even if not used, but will result in a faster loading for the end client.

There is no “one rule to rule the all” situation here as the solution really depends on the use case, but I am going to detail below my personal thinking used when trying to decide which direction to use.

V-IF

I would personally use this directive in the following cases. When referring to “component” in the following list, we refer to the element of component that is assigned to the v-if directive.

  • If the component may NOT actually be rendered at all (for example just if a user is an admin)
  • If the component is very complex (nested components within the component )
  • If the component requires lots of API requests to fetch its data
  • If the component is not a primary component
  • If the component should NOT keep state between different renders

V-SHOW

I would personally use this directive in the following cases. When referring to “component” in the following list, we refer to the element of component that is assigned to the v-show directive.

  • When the component will be rendered on a normal user flow
  • When the component would take a long time to render (for example it has a API request that takes 1 second)
  • When the component is very simple.
  • When the component should just be mounted once
  • When required to use $refs on load even when hidden

Possible side effects or issues caused by miss-use

I have written this article because there can be a number of issues or side effects caused by the misuse of his directives.

$refs to available with v-if

The first and most common issue is that due to the fact that using v-if prevent the element from actually being rendered on the page, also means that refs are not available (as there is nothing to assign to ref in the DOM).

If you require to access the component even if it is hidden, you should use v-show instead.

The component is mounted multiple times

A very advanced (or hard to find a bug) is when you require mounted to just happen once within your workflow.

Due to the fact that v-if is just rendered in the DOM when its value is true, also meant that all his methods and lifecycle are just triggered when the value of v-if is true. What this means is that creating a component that would toggle between its visibility using v-if will mean a full remount of the component.

A live example can be seen in the following Vue SFC playground. In this example, we can see that the v-show element is triggered immediately, while the v-if is just triggered when we click the checkbox (and over and over again if we click and unclick it).

This can cause problems, for example in one example we were running a “log” that was recorded when a section of the page was shown but showing it using v-if was actually resulting in incorrect data being recorded.

State is lost between renders

It can be very common that you may be required to keep a state between different renders of a component. Let’s take for example a sidebar that allows the user to keep notes or do other actions. If you would use v-if to show the sidebar, its content would disappear and reset every time the sidebar is opened.
I have personally seen people creating vuex implementation and other hacks to avoid this issue, while a simple solution would have been to use v-show instead.
NOTE: It is also possible to cache a component while using v-if using <a href="https://vuejs.org/guide/built-ins/keep-alive.html" rel="noreferrer noopener" target="_blank"><KeepAlive></a>, but this is an advanced concept and misuse of it can result in slow application and performance.

Summary

I really hope the above will help you write more performant code and provide you with the information you need to make the correct choice in the future development of your application. As I already mentioned above, please feel free to comment below if you have any comments or personal examples that could be added to this article to support future users.

Top comments (0)