A basic Vue.js tutorial
A very basic address book implemented with Vue.js.
The source code for this tutorial is available on github.
Installing the dependencies
Let’s first define our requirements. We'll need Vue.js and Bootstrap.
package.json
"name": "vuejs-address-book-tutorial",
"version": "1.0.0",
"dependencies": {
"bootstrap": "^3.3",
"vue": "^2.1"
}
}
From the command line:
Install live-server so that we can run the app locally and have it updated automatically whenever we edit the source files.
live-server
Setting up the HTML
Let's create the main files:
index.html
<html>
<head>
<meta charset="utf-8">
<title>Vue</title>
<!-- CSS -->
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<!-- navigation bar -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand">
<i class="glyphicon glyphicon-bullhorn"></i> Vue Address Book
</a>
</div>
</nav>
<!-- main body of our application -->
<div class="container" id="contacts">
<!-- add an event form -->
<div class="row">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Add a contact</h3>
</div>
<div class="panel-body">
</div>
</div>
</div>
<!-- show the contacts -->
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Address book</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JS -->
<script src="node_modules/vue/dist/vue.js"></script>
<script src="app.js"></script>
</body>
</html>
The element with an id of contacts is our target area for the application. As we’ll see in the next section, we need to create a Vue instance for each part of the application that we want to target.
Creating a Vue instance
Within app.js, let’s setup a new Vue instance and target the contacts section of the HTML by setting it on the el key.
app.js
// We want to target the div with an id of 'contacts'
el: '#contacts'
});
At this point, Vue is available anywhere within div#contacts. Before setting up the rest of the HTML, let’s setup the other keys that we’ll need for our Vue instance and cover what they are responsible for.
app.js
// We want to target the div with an id of 'contacts'
el: '#contacts',
// Here we can register any values or collections that hold data
// for the application
data: {},
// Methods we want to use in our application are registered here
methods: {}
});
- The
datakey will be the object where all our ViewModel data is registered - The
methodskey is where we can register custom methods for the application
Displaying data
Let's add some initial data to the app.
app.js
contact: { surname: '', given_names:'', gender:'', dob:'' },
contacts: [
{
id: 1,
surname: 'Smith',
given_names: 'John',
gender: '1',
dob: '2045-09-10'
},
{
id: 2,
surname: 'Smith',
given_names: 'Mary',
gender: '0',
dob: '2046-08-05'
}
]
},
And let's display it.
index.html
<div class="panel-heading">
<h3>Address book</h3>
</div>
<ul class="list-group">
<li class="list-group-item" v-for="(contact, index) in contacts">
<h4 class="list-group-item-heading">
{{ contact.given_names }} {{ contact.surname }}
</h4>
<h5>
<i class="glyphicon glyphicon-calendar" v-if="contact.dob"></i> {{ contact.dob }}
</h5>
</li>
</ul>
</div>
Note the v-for directive that allows us to loop through the list of contacts.
Adding the form
Our form will need inputs for the contact details. We’ll use the native HTML5 datepicker for selecting the event date.
This will not work in Firefox.
index.html
<div class="panel-heading">
<h3>Add a contact</h3>
</div>
<div class="panel-body">
<div class="form-group">
<input class="form-control" placeholder="Surname" v-model="contact.surname">
</div>
<div class="form-group">
<input class="form-control" placeholder="Given names" v-model="contact.given_names">
</div>
<div class="form-group">
<label class="radio-inline">
<input type="radio" v-model="contact.gender" value="0"> Female
</label>
<label class="radio-inline">
<input type="radio" v-model="contact.gender" value="1"> Male
</label>
</div>
<div class="form-group">
<input type="date" class="form-control" placeholder="Date of birth" v-model="contact.dob">
</div>
<button class="btn btn-primary" v-on:click="addContact">Submit</button>
</div>
</div>
Each form widget has a v-model directive assigned to the relevent property of the contact object. This binds the form widgets to the contact object.
The submit button element has the v-on directive with a value of :click="addContact" on it. We pass a method to be run on the click event.
Processing the form
app.js
// Adds a contact to the existing contacts array
addContact: function() {
if (this.contact.surname) {
this.contacts.push(this.contact);
this.contact = { surname: '', given_names: '', gender: '', dob: '' };
}
}
Deleting a contact
We add a delete button on each contact and map it to the deleteContact method via the v-on:click directive. When the button is clicked, the deleteContact method will be invoked.
index.html
<li class="list-group-item" v-for="(contact, index) in contacts">
<h4 class="list-group-item-heading">
{{ contact.given_names }} {{ contact.surname }}
</h4>
<h5>
<i class="glyphicon glyphicon-calendar" v-if="contact.dob"></i> {{ contact.dob }}
</h5>
<button class="btn btn-xs btn-danger" v-on:click="deleteContact(index)">Delete</button>
</li>
</ul>
The deleteContact method is added to the Vue instance's methods:
app.js
...
deleteContact: function(index) {
if (confirm("Are you sure you want to delete this contact?")) {
this.contacts.splice(index, 1);
}
}
}