Introduction to Vue.js - part one

Introduction to Vue.js - part one

Published 10. jul 2018 12:03 by Stein Ove Helset

In this introduction to Vue.js we're going to show you how to build a simple business generator. We'll be covering things like components, methods, props and similar.

What is Vue.js?

" Vue (pronounced /vju?/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries. "
-From the Vue.js official website Read more Vue at their official website: http://vuejs.org/

What are we going to create?

As a starter project for learning Vue you don't want to build something too big or complicated. You want to build something you can finished and actually understand what you're doing. In this tutorial series we are going to build a simple business card "generator". We will have a form where you can fill out all the information and a business card previewer with front and back.

We'll be adding the possibility of multiple styles to the business cards and the project will evolve the more we learn. Let's go ahead and set up the project so we can get started :-)

Setting up the project

This tutorial assume that you have basic knowledge of HTML, CSS and JavaScript. We are trying to do this as easy as possible so we avoid using the vue-cli. The first thing you can do is to create a new folder on your computer and inside that create a new file called index.html. Write the following code into index.html (Don't just copy):


<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        
        <style><!-- Add a simple style block -->
            * {<!-- Reset magin, padding og set the box sizing -->
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            
            body {<!-- Set global font and light grey background to the whole website -->
                font-family: 'Verdana', 'Arial';
                background: #f9f9f9;
            }
        </style>
    </head>

    <body>
        <div id="businesscard"> <!-- This will be the wrapper around our Vue app -->
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- Include Vue -->
        
        <script>
            new Vue({ /* Create a new Vue instance */
                el: '#businesscard', /* Bind the Vue instance to the #businesscard - div */
            })
        </script>
    </body>
</html>

I'm keeping both the scripts and the styles in the same file. I'm doing this just to keep it as simple as possible. If you want you can split both the style and the scripts into separate files. This is about as simple as you can get when it comes to setting up a Vue project. In the next part we'll be adding some more styles, adding the the form and the preview box.

Adding some more code

Add this style inside the style tag:


hr {
    width: 100%;
    height: 1px;
    margin: 20px 0;
    border: 0;
    background: #eaeaea;
}

#businesscard {
    width: 1000px;
    margin: 100px auto;
    font-size: 0;
    background: #fff;
}

    .editor, .preview {
        width: 50%;
        padding: 50px;
        display: inline-block;
        vertical-align: top;
    }

.editor h2 {
    margin-bottom: 15px;
    font-size: 18px;
    font-weight: normal;
    line-height: 18px;
}

.editor label {
    margin-bottom: 10px;
    display: block;
    font-size: 13px;
    color: #999;
}

.editor input {
    height: 40px;
    margin-bottom: 15px;
    padding-left: 15px;
}
    
.preview .card-front {
    width: 100%;
    height: 200px;
    margin-bottom: 50px;
    position: relative;
    font-size: 14px;
}

.preview .card-back {
    width: 100%;
    height: 200px;
    position: relative;
    font-size: 14px;
}

Nothing major here. It's just code for placing the app on the middle of the screen and splitting it into two pieces. We're also adding some style to the label and input, and also the preview right there at the bottom.

We need to add some elements to the data array which we're going to use. Change the contents of the script tag accordingly:


new Vue({
    el: '#businesscard',
    data: {
        name: '', // Some variables for the content of the business card
        position: '',
        company: '',
        slogan: '',
        phone: '',
        email: '',
        website: '',
        logo: null,
    
        type: 'default' // Set default business card style to default
    }
})

Last part of this section is to add some more HTML. Add this content inside the <div id="businesscard"></div> tag:


<div class="editor">
    <h2>Company</h2>
    
    <label>Logo</label><br>
    <input type="file">
    
    <label>Name</label><br>
    <input type="text" v-model="company" placeholder="Name..."> <!-- Use v-model="" to bind the input field to the variable -->
    
    <label>Slogan</label><br>
    <input type="text" v-model="slogan" placeholder="Slogan...">
    
    <hr>
    
    <h2>Employee</h2>
    
    <label>Name</label><br>
    <input type="text" v-model="name" placeholder="Name...">
    
    <label>Position</label><br>
    <input type="text" v-model="position" placeholder="Position...">
    
    <label>Phone</label><br>
    <input type="text" v-model="phone" placeholder="Phone...">
    
    <label>Email</label><br>
    <input type="text" v-model="email" placeholder="Email...">
    
    <label>Website</label><br>
    <input type="text" v-model="website" placeholder="Website...">
    
    <hr>
    
    <h2>Style</h2>
    
    <select v-model="type">
        <option value="default" selected>Default</option>>
        <option value="blue" selected>Blue</option>>
    </select>
</div>

<div class="preview">
    <div class="card-front" :data-type="type">
        <div class="content">
            <span class="logo"><img v-if="logo" :src="logo" /></span>
            <span class="company">{{ company }}</span>
            <span class="slogan">{{ slogan }}</span>
        </div>
    </div>
    
    <div class="card-back" :data-type="type">
        <span class="name">{{ name }}</span>
        <span class="position">{{ position }}</span>
        <span class="phone" v-if="phone">[P]: {{ phone }}</span>
        <span class="email" v-if="email">[@]: {{ email }}</span>
        <span class="website" v-if="website">[W]: {{ website }}</span>
    </div>
</div>

If you have saved the file and try to open it in your browser you will see a form to the left and the business card previewer to the right. If you fill in the company name or one of the other fields you will see that the fields inside the business card previewer is updated automatically. This is the wonder of Vue.js two way databinding.

Different styles to the business cards

When you tested the code in the last sections. You probably saw that the business card looked awful. Now we are going to add two different styles to the business card. Add this code at the bottom of your style tag:


/* Default card */

.preview .card-front[data-type='default'] {
    text-align: center;
    border-bottom: 3px solid #eaeaea;
    background: #fafafa;
}

    .preview .card-front[data-type='default'] .content {
        position: relative;
        top: 50%;
        
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
    }
    
    .preview .card-front[data-type='default'] img {
        max-width: 60px;
        max-height: 60px;
        margin-bottom: 15px;
    }
    
    .preview .card-front[data-type='default'] span {
        width: 100%;
        display: block;
    }
    
        .preview .card-front[data-type='default'] .company {
            margin-bottom: 20px;
            font-size: 28px;
        }
        
        .preview .card-front[data-type='default'] .slogan {
            font-size: 16px;
            color: #999;
        }

.preview .card-back[data-type='default'] {
    padding: 20px;
    border-bottom: 3px solid #eaeaea;
    background: #fafafa;
}

    .preview .card-back[data-type='default'] span {
        width: 100%;
        display: block;
    }
    
    .preview .card-back[data-type='default'] .name {
        font-weight: bold;
    }
    
    .preview .card-back[data-type='default'] .phone {
        position: absolute;
        bottom: 80px;
    }
    
    .preview .card-back[data-type='default'] .email {
        position: absolute;
        bottom: 50px;
    }
    
    .preview .card-back[data-type='default'] .website {
        position: absolute;
        bottom: 20px;
    }

/* Blue card */

.preview .card-front[data-type='blue'] {
    text-align: center;
    border-bottom: 3px solid #2e8cd2;
    background: #49b1ff;
}

    .preview .card-front[data-type='blue'] .content {
        position: relative;
        top: 50%;
        
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
    }
    
    .preview .card-front[data-type='blue'] img {
        max-width: 60px;
        max-height: 60px;
        margin-bottom: 15px;
    }
    
    .preview .card-front[data-type='blue'] span {
        width: 100%;
        display: block;
    }
    
        .preview .card-front[data-type='blue'] .company {
            margin-bottom: 20px;
            font-size: 28px;
            color: #fff;
        }
        
        .preview .card-front[data-type='blue'] .slogan {
            font-size: 16px;
            color: #2e8cd2;
        }

.preview .card-back[data-type='blue'] {
    padding: 20px;
    border-bottom: 3px solid #2e8cd2;
    background: #49b1ff;
    color: #fff;
}

    .preview .card-back[data-type='blue'] span {
        width: 100%;
        display: block;
    }
    
    .preview .card-back[data-type='blue'] .name {
        font-weight: bold;
    }
    
    .preview .card-back[data-type='blue'] .phone {
        position: absolute;
        bottom: 80px;
    }
    
    .preview .card-back[data-type='blue'] .email {
        position: absolute;
        bottom: 50px;
    }
    
    .preview .card-back[data-type='blue'] .website {
        position: absolute;
        bottom: 20px;
    }

When we select a style in the drop down in the form we set the value of the variable "type" to either blue or default. This is then inserted into the data-type attribute of the business card previewer. This makes us able to select the business card based on a attribute (.card-back[data-type='blue']).

Logo uploader

If you tried the logo uploader you noticed that there is no preview. Let's add a method to our Vue app so we can show a preview of the uploaded logo. Add this right beneath the data array:


# Vue

methods: {
    onFileChange(e) {
        const file = e.target.files[0];
        this.logo = URL.createObjectURL(file);
    }
}

# HTML

@change="onFileChange" <!-- Add this to the <input type="field"> -->

That was not a lot of code to make this possible. We take the file from the form and let JavaScript do some magic so we can the the url. We then assign that to our logo variable. And voila the logo will show inside the previewer when you upload one.

Summary

This was part one of this series. We'll be posting more parts of this series soon and they will include more business card styles, turning some of the code into reusable compoentents, how to communicate with the components and much more.

If you're interested in getting notified when we're posting the tutorials you can sign up to our newsletter at the bottom of the screen!

Share this post

Comments

No comments yet

Add comment