VueJS is a popular web development framework for building browser-based user interfaces. This tutorial provides a short introduction to getting started with developing VueJS applications.

Filed under

Overview

Vue is a Javascript library and development framework primarily for building user interfaces. Vue allows the developer to manipulate the elements on the browser interface in real time, and it also provides features for binding data to elements, which helps users in manipulating and assigning values to HTML attributes. Vue can more easily be integrated with existing projects since it uses HTML, CSS and Javascript separately, and does not force a specific overall structure on the application.

Setup

In this tutorial, we will be creating a small web app that can search for user accounts on GitHub. We will be using the GitHub Rest API for this tutorial. To properly follow this tutorial, you should create an OAuth App in your GitHub account to obtain a client_id and client_secret which are required when using GitHub API. You can create one following this link (a free GitHub account is required):

Getting Started

Create our project directory named github-profile-viewer and create the project directory structure as illustrated below:

github-profile-viewer/
	index.html

Then add a basic template code for an HTML page in our index.html:

<html>
	<head>
		<title>GitHub Profile Viewer</title>
	</head>
	<body>
	</body>
</html>

There's nothing special here yet but you can try to check the output of this by opening the HTML file in your browser. Next, we want to include the Vue library and see if VueJS is properly running on our page. To do this, add this line of code in our head tag:

<script src="https://unpkg.com/vue"></script>

Then create a new directory inside our project directory called js and create an empty JS file named app.js. Our project structure should look like this by now:

github-profile-viewer/
	js/
		app.js
	index.html

In our app.js file, create a new Vue instance and pass the configuration as shown below:

new Vue({
	el : "#app",
	data : {
		message : "Hello World!"
	}
})

Then modify our index.html file to match the code shown below:

<html>
	<head>
		<title>GitHub Profile Viewer</title>
		<script src="https://unpkg.com/vue"></script>
	</head>
	<body>
		<div id="app">
			{{ message }}
		</div>
	</body>
	<script src="js/app.js"></script>
</html>

Let's review first the things that we have done so far. First, in our app.js file, we have created a new Vue instance and pass a configuration object. The el property tells Vue where to bind itself on the page, on our case, it's the div with the id app. The data property holds the values for our data you want Vue to hold. Since we want our message to appear inside our page, we have included this line inside our div:

{{ message }}

Those double curly braces are one way to include a data in our DOM. If you open the HTML file in your browser, you should have "Hello World" displayed in your page.

Since we will be creating a simple web app for a GitHub user search functionality, we want the user to be able to input any username to search. Also, we want to include some CSS styling on our page to make it look nicer.

Modify our index.html file so we could have a textbox for our user to input as shown below:

<div id="app">
	<h3>GitHub Profile Viewer</h3>
	<section class="box">
		<input type="text" placeholder="Type the username and press enter" />
	</section>
</div>

Now, create a new directory inside our project directory named css and create a new file called style.css inside our css directory. Then place the following CSS rules:

* {
	box-sizing: border-box;
}
body {
	padding: 50px 20px;
	background-color: #24292e;
}
h3 {
	color: #ffffff;
	text-align: center;
	margin-bottom: 40px;
}
.box {
	width: 600px;
	max-width: 100%;
	min-height: 500px;
	margin: 20px auto 50px;
	border: 1px solid #eee;
	padding: 40px 20px;
	-webkit-box-shadow: 0 0 15px 0 rgba(247, 245, 245, 0.05);
	box-shadow: 0 0 15px 0 rgba(247, 245, 245, 0.05);
	background-color: #f4f7fc;
	overflow: hidden;
	position: relative;
}
input[type=text] {
	border: 1px solid #ddd;
    width: 100%;
	transition: all ease-in 0.25s;
	line-height: 2em;
    display: inline-block;
    padding: 0.2em 1em;
	font-size: 1em;
	text-align: center;
}
input:focus {
    outline: none;
    border: 1px solid #24292e;
}

Now we will link the style sheet in the HTML file. Add this tag inside your head element:

<link rel="stylesheet" type="text/css" href="css/style.css" />

By now, if you open the HTML file in your browser, you should have in your page a nice looking white box in the center which contains our input. As you can notice in our input tag, our placeholder say's this Type the username and press enter, but how should we do this?

Handling Events

Now we want a specific method to be called when the user presses the ENTER key. To do this, modify our app.js file so we can include a method named searchUser in our Vue instance as shown below:

new Vue({
	el : "#app",
	data : {
	},
	methods : {
		searchUser() {
		}
	}
})

Then in our index.html, modify our input tag so we can include this attribute v-on:keyup.enter="searchUser". The input tag should look like this:

<input type="text" placeholder="Type the username and press enter" v-on:keyup.enter="searchUser" />

As you can see above, we are using the v-on directive to attach event listeners.

Vue also provides a v-model directive that creates a two-way binding between form input and app state. We want to have a username property in our data object in our app.js file as shown below:

new Vue({
	el : "#app",
	data : {
		username : ""
	},
	methods : {
		searchUser() {
		}
	}
})

Modify our input tag so we have the v-model attribute:

<input type="text" placeholder="Type the username and press enter" v-model="username" v-on:keyup.enter="searchUser" />

In this case, every time the user types in our input tag, the value in our input tag is being attached to our username property.

Now it's time to make some API calls. In our app.js, include your newly created GitHub OAuth app's client_id and client_secret as shown below:

const clientId = "<YOUR_CLIENT_ID>"
const clientSecret = "<YOUR_CLIENT_SECRET>"

Then create a new method called getUserProfile in our Vue instance which accepts one parameter. The method will make an API call to a GitHub endpoint and then turn the response to a JSON format as shown below:

async getUserProfile(username) {
	let apiUrl = "https://api.github.com/users/" + username + "?client_id=" + clientId + "&client_secret=" + clientSecret
	let response = await fetch(apiUrl)
	return await response.json()
}

Now we want to call our getUserProfile method in our searchUser method, but only if our property username has a value. Modify our searchUser method as shown below:

async searchUser() {
	if(this.username) {
		await this.getUserProfile(this.username)
	}
}

NOTE: As you can see, we have added the keyword async before the method name searchUser. This declares the method asynchronous and allows us to use the await keyword that provides a simpler syntax to deal with code executing in the background. Read more about Javascript async functions.

And there it is, you have created a simple web app. Every time a user types a username in the input tag and presses ENTER, the program will make an API call to a GitHub endpoint. But wait, we are not actually displaying the actual response in our page.

Conditional Rendering

With conditional rendering, we want to display specific DOM or data when the condition is met with the help of if, if-else, etc. In this case, we only want a specific data to be displayed when the user press the ENTER, but we also want that by default, we will a display a User not found message. To do this, modify our index.html and add this block of code after our input tag:

<transition name="slide-fade" v-if="!this.userdata.id">
	<p class="message">No user found</p> 
</transition> 

In the above code, the transition element which contains our default message will only show if the condition v-if="!this.userdata.id" is not true, but what does this.userdata.id mean? The this.userdata.id property is the data in the response received from our GitHub API call earlier. But currently, if you refresh our page, this will give you an error in your console "TypeError: Cannot read property 'id' of undefined". This is because our HTML file does not know yet about the response received from GitHub API call. To access the response outside our app.js file, add a userdata property in our data object as shown below:

data : {
	username : "",
	userdata : {}
}

Adding the userdata property in our data object will make the error go away(if you refresh the page) but this is still not right since our userdata property does not have a value yet. Modify our searchUser method so everytime we make a call to the getUserProfile method, the return value of the method getUserProfile will be assigned to the property userdata as shown below:

async searchUser() {
	if(this.username) {
		var userProfile = await this.getUserProfile(this.username)
		if(userProfile) {
			this.userdata = userProfile
		}
	}
}

Now modify our index.html file so we can display the data received from GitHub API. Add the following in our index.html after our default message transition tag:

<transition name="user-profile" v-if="this.userdata.id">
	<div class="user-profile">
		<a href="#" target="_blank"><img alt="" class="avatar" :src="userdata.avatar_url" height="150" width="150"></a>
		<a href="#" class="name">{{ userdata.name }}</a>
		<div>
			<div class="count-container">
				<div class="counter">{{ userdata.public_repos }}</div>
				<div class="counter-label">Repositories</div>
			</div>
			<div class="count-container">
				<div class="counter">{{ userdata.followers }}</div>
				<div class="counter-label">Followers</div>
			</div>
			<div class="count-container">
				<div class="counter">{{ userdata.following }}</div>
				<div class="counter-label">Following</div>
			</div>
		</div>
	</div>
</transition>

In the above code, we are accessing different properties in our response from GitHub's API such as the user's name, public repositories, number of followers/following and the user's avatar.

NOTE: When specifying the src attribute in an img tag, you should do it like below:

<img :src="userdata.avatar_url" height="150" width="150">

In this case, the img tag will get the actual value of the property userdata.avatar_url instead of the image resource userdata.avatar_url. You can test it now to see if it actually displays the actual response of the GitHub API. You can refresh the page to make sure the changes made in our HTML and JS file are applied.

Let's add some more CSS styling to make the display from the response look better. Edit our style.css file and add the following:

.message {
	font-weight: bold;
	text-align: center;
	margin: 40px 0;
}
.user-profile {
	margin-top: 40px;
	text-align: center;
}
.user-profile > * {
	display: block;
	width: 100%;
	padding: 8px;
}
.avatar {
	border-radius: 50%;
}
.name {
	font-weight: bold;
	text-decoration: none;
	text-transform: capitalize;
	color: #24292e;
	font-size: 2em;
}
.count-container {
	display: inline-block;
	padding: 18px;
}
.counter {
	font-weight: bold;
	font-size: 1.3em;
}

And there it is! You have now a complete working web app created using VueJS! You can check this demo for a full working sample of this program.


Twitter Facebook LinkedIn Youtube Slideshare Github