loading...
Cover image for An introduction to Vue.js - Chapter 5 - Conditional Rendering

An introduction to Vue.js - Chapter 5 - Conditional Rendering

neradev profile image Moritz Schramm ・4 min read

Series overview

Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5

Foreword

I was away for some time and did not manage to write an article for you guys. But today we are continuing with our Vue.js series. Lets talk about conditional rendering in Vue and lets try to adapt our list so that we can use the list as a ordered and unordered list.

I will always upload the code to this github repository.

Conditions

We all know how we can do a conditional execution in JavaScript. Usally you have something like that:

if (a === b) {
    // Execute some code if it is true
} else {
    // Execute some code if it is false
}

Even though some times you need something like that:

if (a === b) {
    // Execute some code if the first condition is true
} else if (b === c) {
    // Execute some code if then second condition is true
} else {
    // Execute some code if both conditions are false
}

Now sometimes you want to render certain things only if a certain condition is true or even not. For that luckily Vue offers more directives called v-if, v-else and v-else-if.

v-if

The v-if is the most simple one. You can just add this to your corresponding DOM node that you only want to render under a certain circumstance. For example we want the possibility to differ between an ordered and unordered list. Of course we could simply duplicate our already existing list but we could also just change the rendered tag based on a boolean expression.

First I added an additional property to our list component:

import template from './list.html';

export default {
    name: 'vg-list',
    template,
    props: {
        items: {
            type: Array,
            required: true
        },
        ordered: {
            type: Boolean,
            required: false,
            default: false
        }
    }
};

(If you do not have a clue yet about this, read the previous chapters ;))

Now we have a look at our HTML template. We want to render an ul tag if ordered === false and an ol tag if ordered === true. When you add the v-if directive to your DOM node you set the value to the boolean expression you want to check.

<ol v-if="ordered === true" class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ol>
<ul v-if="ordered === false" class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ul>

Of course you could simply change the boolean to the shorthand expression

<ol v-if="ordered" class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ol>
<ul v-if="!ordered" class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ul>

If you know would start the app, you should get an error since it is not allowed to have multiple root nodes within one component. At some point in the Vue history it was not possible to do such stuff without an additional container element around that. But since v2.0.1 they made it possible to have multiple root nodes when using v-if and v-else.

v-else

The v-else directive always reacts to the last v-if or v-else-if directive that was called before and on the same node level. You do not need to set any value to this new "attribute". It behaves like the usual else block in your JavaScript code.

To adapt now our code we just need to remove the second v-if directive and replace it by a v-else one.

<ol v-if="ordered" class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ol>
<ul v-else class="list">
    <li v-for="item in items" class="list-element">{{ item }}</li>
</ul>

If you now start your app it should actually work without an error message in your developer tools.

v-else-if

I could not think of any example where I would you such a thing. Actually I would prefer to rethink your component structure and maybe split them up into multiple ones (for sharing logic you could use mixins but about that we will talk later). That is why I will not go deep into that topic.

Basically it behaves like a combination of the other two. It needs to have a boolean expression as the value and it always reacts to the last v-if or v-else-if directive on the same node level.

If you want to have further reading, check the API documentation for that. ;)

Pass boolean parameters

While writing that article I noticed some missing knowledge from my side on how to pass a boolean to a component from your HTML template. Usually, I would use a property and bind that one to the component but that do not make sense at all when using such a list component. When just doing this:

<div class="app">
    <h1>Hello World</h1>
    <vg-button text="Foo bar" />
    <vg-list :items="items" ordered="true" />
    <vg-list :items="items" />
</div>

We would get a "Expected Boolean, Got String." error. That is why I looked it up and it is actually pretty easy. You just need to bind the boolean value to the component:

<div class="app">
    <h1>Hello World</h1>
    <vg-button text="Foo bar" />
    <vg-list :items="items" :ordered="true" />
    <vg-list :items="items" />
</div>

or

<div class="app">
    <h1>Hello World</h1>
    <vg-button text="Foo bar" />
    <vg-list :items="items" v-bind:ordered="true" />
    <vg-list :items="items" />
</div>

That actually works because the value of the v-bind directive is executed as JavaScript code and the return value is passed to the bound component.

Done

I hope you like the guide. If you have any questions ask them on Twitter or in the comment section. I will try to answer a much as possible. I am happy about any possible feedback.

Next chapter will come in the next days.

Posted on by:

neradev profile

Moritz Schramm

@neradev

I am a passionated web developer and love to work with new tools.

Discussion

markdown guide