Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
In this article, we’ll look at various ways to render items conditionally on the screen with Vue.js by using the v-if
, v-else-if
and v-else
directives.
v-if
The v-if
directive is used to conditionally render a block. The block with the v-if
attribute will be rendered only if the directive’s expression returns a truthy value.
For example, in src/index.js
we put:
new Vue({
el: "#app",
data: {
show: true
}
});
Then in index.html
, we put:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<div v-if="show">
Hi
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then Hi
will be shown since show
is set to true
.
We can also use v-else
in addition to v-if
if we want to show something if an expression returns false
.
For example, if we change true
to false
in src/index.js
:
new Vue({
el: "#app",
data: {
show: false
}
});
Then in index.html
, if we have:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<div v-if="show">Hi</div>
<div v-else>Bye</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we see Bye
because show
is set to false
and we have v-else
directive added to an element that is the sibling of the element that immediately follows the element with thev-if
directive.
v-if on template Elements to Toggle Groups of Elements
We can add v-if
to a group of elements by wrapping them around a template
element.
For example, we can write:
<template v-if="show">
<p>foo</p>
<p>bar</p>
</template>
Then foo
and bar
will be shown if show
is set to true
.
v-else
We can use the v-else
directive to display something when the expression in the v-if
directive in a sibling element that immediately follows the element with v-if
returns false
.
For example, we can display messages randomly as follows. In index.html
, we put:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<div v-if="Math.random() > 0.5">
Hi
</div>
<div v-else>
Bye
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
And in src/index.js
, we put:
new Vue({
el: "#app",
data: {}
});
v-else-if
v-if
can also be followed with an element with the v-else-if
directive, so that we can have multiple elements conditionally displayed.
For example, we can write index.html
as follows:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<div v-if="Math.random() > 0.8">
A
</div>
<div v-else-if="Math.random() > 0.5 && Math.random() <= 0.8">
B
</div>
<div v-else>
C
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we’ll have A, B and C displayed according to what’s returned from Math.random()
.
This is available since Vue 2.1.0.
Controlling Reusable Elements with key
Vue tries to reuse existing elements as much as possible when conditionally rendering items.
This means sometimes we get things that we don’t expect.
For example, if we have the following in src/index.js
:
new Vue({
el: "#app",
data: {
loginType: "username"
},
methods: {
toggleType() {
this.loginType = this.loginType === "username" ? "email" : "username";
}
}
});
And the following in index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<button @click="toggleType">Change Login Type</button>
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" />
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" />
</template>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then when we click the Change Login Type button after entering something to the input, we get the same input value displayed after changing the template.
To make the input render from scratch, we can add a key
attribute to the the key
attribute with different values for each input.
So instead of what we have above for index.html
, we can write:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<button @click="toggleType">Change Login Type</button>
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username" />
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email" />
</template>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then the inputs will be cleared.
Everything else is still reused efficiently since we didn’t add the key
attribute.
Conclusion
We can render things conditionally with v-if
. The element with v-if
added will be displayed when the expression that we set as the value returns true
.
We can use it in conjunction with v-else-if
and v-else
, where we can provide elements that are displayed when the condition in v-if
returns false
.
Elements with v-else-if
are displayed when the condition returns a truthy value and the one in v-if
returns a falsy value. It must be added immediately below an element with v-if
.
An element with v-else
can be added below an element with v-if
if there’s no element with v-else-if
. If there’s one or more elements with v-else-if
, then the v-else
element has to be added below it.
v-else
can be used to display something if all other conditions are falsy.