5th December, 2016: This tutorial covers Vue.js 1.x. If you’re looking for Vue 2 content, see here: Getting up and Running with the Vue.js 2.0 Framework.
21st July, 2016: Article has been updated to cover Vue.js 1.0.x, and a section on components added.
Vue.js is a JavaScript library that helps you build web applications using the the MVVM (Model-View-ViewModel) architectural pattern. At first glance, it might seem quite similar to AngularJS, but once you start working with it you’ll quickly realize that Vue.js is not only much simpler and easier to learn, but also more flexible.
In this introductory tutorial, I’ll teach you the basic concepts of Vue.js, and give a complete overview of its most important features.
Vue.js 1.0.x has a few syntax changes that are not compatible with Vue.js 0.12.x. If you have experience using those early versions, you might have already noticed some of the changes in this tutorial. You can get an overview of all the changes here: What’s New in Vue.js 1.0
Adding Vue.js to Your Page
Though you can get the latest release of Vue.js from GitHub, you might find it easier to load it from a CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js">
</script>
Creating a View-Model
In Vue.js, view-models are created using the Vue
class. If you are wondering what a view-model is, you can think of it as an object that makes it very easy for you to display your model’s data inside a view (you can treat any object literal as a model, and any HTML UI element as a view).
To see how a view-model works, let’s start by creating a view. An empty <div>
will do for now:
<div id="my_view">
</div>
And here’s an object literal which will be our model. As it deals with JavaScript code, make sure you create it inside a <script>
tag, or in a separate JS file.
var myModel = {
name: "Ashley",
age: 24
};
Now that we have a view and a model, it’s time to create a view-model (a Vue
instance) that binds both together:
var myViewModel = new Vue({
el: '#my_view',
data: myModel
});
As you can see, the el
property points to the view (you can use any CSS selector here), and the data
property points to the model. Our view-model is now ready to be used.
To display your model’s data inside the view, you should use mustache-style bindings. For example, to display the age
property of your model you would add the string {{ age }}
inside your view. The following code snippet uses both the properties of the model:
<div id="my_view">
{{ name }} is {{ age }} years old.
<!-- Evaluated to "Ashley is 24 years old" -->
</div>
Any changes you make to your model will be instantly visible in the view.
Creating Two-Way Bindings
The mustache-style binding we used in the previous example is a one-way binding. This means that it can only show the data of the model, not modify it. If you want to allow the view to edit the model you should create a two-way binding instead, using the v-model
directive.
Let’s change our view so that it contains an input
element whose v-model
points to the name
property:
<div id="my_view">
<label for="name">Enter name:</label>
<input type="text" v-model="name" id="name" name="name" />
<p>{{ name }} is {{ age }} years old.</p>
</div>
At this point, if you edit the value in the input field, your model will change immediately.
See the Pen XbYZBJ by SitePoint (@SitePoint) on CodePen.
Using Filters
A filter is a function you can use inside a directive or a mustache-style binding. A filter is always preceded by a pipe symbol (|
). For example, if you want to display the name
property in uppercase, your mustache-style binding would look like this:
{{ name | uppercase }}
Also in this case, there’s a demo for filters that you can examine:
See the Pen MwXQBM by SitePoint (@SitePoint) on CodePen.
The filters lowercase
and capitalize
can be used in a similar manner.
We’ll talk more about filters in the next section.
Rendering Arrays
If your model has an array, you can display the contents of that array by adding a v-for
directive to a list’s <li>
element. To demonstrate that, let’s add an array to our model:
var myModel = {
name: "Ashley",
age: 24,
friends: [
{ name: "Bob", age: 21 },
{ name: "Jane", age: 20 },
{ name: "Anna", age: 29 }
]
};
The following code shows you how to display the name
property of every object in the friends
array:
<div id="my_view">
<ul>
<li v-for="friend in friends"> {{ friend.name }} </li>
</ul>
</div>
To change the order in which the elements are listed, use the orderBy
filter inside the v-for
directive. For example, if you want to order the elements by age
, your code should be as follows:
<div id="my_view">
<ul>
<li v-for="friend in friends | orderBy 'age'"> {{ friend.name }}</li>
</ul>
</div>
You can also render items conditionally. To achieve this task, use the filterBy
filter. For example, the following example shows how to render only those items which contain the character “a” in the name
field:
<div id="my_view">
<ul>
<li v-for="friend in friends | filterBy 'a' in 'name'"> {{ friend.name }} </li>
</ul>
</div>
This third demo uses a two-way data binding and a filterBy
filter to simulate a search:
See the Pen Example of using filterBy to filter items by SitePoint (@SitePoint) on CodePen.
Handling Events
In Vue.js, if you need to handle events associated with your view, you should add event handlers inside the view-model’s methods
property. Inside all Vue.js event handlers, you can use this
to access the items in the data model.
The following view-model contains a click handler:
var myViewModel = new Vue({
el: '#my_view',
data: myModel,
// A click handler inside methods
methods: {
myClickHandler: function(e) {
alert("Hello " + this.name);
}
}
});
To associate an event handler defined in the view-model with one or more UI elements in the view, you should use the v-on
directive. For example, the following view has a <button>
which uses the v-on
directive to call myClickHandler
:
<div id="my_view">
Name: <input type="text" v-model="name">
<button v-on:click="myClickHandler">Say Hello</button>
</div>
Putting these snippets together, results in this demo for click handler:
See the Pen Example of event handling by SitePoint (@SitePoint) on CodePen.
Creating Components
Vue.js allows you to create custom HTML elements that can be used within your views. By using such elements, you can make your code not only more concise, but also more readable.
To define and register a custom HTML element, you must create a Vue component using the component
method of the Vue
class. You can specify the contents of the custom element using the component’s template
property.
Here’s a code snippet that defines and registers a simple custom HTML element called <sitepoint>
.
Vue.component('sitepoint', {
template: '<a href="https://www.sitepoint.com">Sitepoint</span>'
});
The <sitepoint>
element can now be used inside your view just like any other standard HTML element.
<div id="my_view">
<sitepoint></sitepoint>
</div>
Standard HTML elements usually have attributes associated with them that allow you to control how they look and behave. The custom elements you create using Vue.js too can have such attributes. To specify what attributes your element can have, you must use the props
property while creating the associated component.
Here’s how you would add a prop called channel
to the <sitepoint>
element:
Vue.component('sitepoint', {
props: ['channel'],
template: '<a href="https://www.sitepoint.com/{{ channel | lowercase }}">{{ channel }} @Sitepoint</span>',
});
As you can see in the code above, moustache-style bindings can be used to embed the value of a prop inside the template
.
You are now free to use the channel
attribute inside the <sitepoint>
tag. For example, here’s how you can use it to link to two different channels of Sitepoint:
<div id="my_view">
<sitepoint channel="JavaScript"></sitepoint>
<sitepoint channel="Web"></sitepoint>
</div>
Feel free to modify the code in the following demo to experiment with other templates and props.
See the Pen Example of a component with props by SitePoint (@SitePoint) on CodePen.
Conclusion
In this introductory tutorial about Vue.js we’ve looked at how to use one-way and two-way data binding, directives, filters, and events. We’ve also learned how to create your own HTML elements using Vue.js components.
The topics covered, should be enough to start creating interactive web interfaces using this simple framework. If you are looking for more features, such as support for Ajax or routing operations, there are a growing number of Vue.js plugins available to add to your projects.
To learn more about Vue.js, I suggest going through the Vue.js API reference and also having a look at the guide available on the website.
Frequently Asked Questions about Getting Started with Vue.js
What is Vue.js and why should I use it?
Vue.js is a progressive JavaScript framework used for building user interfaces. Unlike other monolithic frameworks, Vue.js is designed from the ground up to be incrementally adoptable. The core library focuses on the view layer only and is easy to pick up and integrate with other libraries or existing projects. Vue.js also perfectly fits in multi-page applications as a feature-rich framework. It offers a lot of functionalities, such as two-way data binding, server-side rendering, Vue-CLI, and optional JSX support.
How do I install Vue.js?
Vue.js can be included directly in your HTML file from a CDN like jsDelivr or unpkg. Alternatively, you can install it via NPM. To install Vue.js using NPM, you need to have Node.js and NPM installed on your machine. Once you have those, you can install Vue.js by running the command npm install vue
.
What is the Vue instance?
A Vue instance is essentially a Vue app. It is created by instantiating Vue with the Vue
function: var vm = new Vue({})
. An instance of Vue is also known as the root Vue instance. It can contain options such as data, computed, watch, methods, lifecycle hooks, etc.
How does Vue.js handle data binding?
Vue.js uses a system called directives to bind data to elements in the DOM. The most basic form of data binding is text interpolation using the “Mustache” syntax (double curly braces) such as {{ msg }}
. Vue.js also provides a v-bind
directive for binding attributes and a v-model
directive for two-way data binding.
What are Vue.js components?
Components are one of the most powerful features of Vue.js. They help you extend basic HTML elements to encapsulate reusable code. Essentially, a Vue component is a Vue instance with pre-defined options. They can be registered globally or locally and can communicate with each other.
How do I create a Vue.js component?
You can create a Vue.js component by using the Vue.component(tagName, options)
method for global registration or by using the components
option for local registration. The options include data, template, methods, computed, watch, etc.
What are Vue.js directives?
Directives are special attributes with the v-
prefix. They are used to apply special reactive behavior to the rendered DOM. Some of the most commonly used directives are v-bind
, v-model
, v-show
, v-if
, v-else
, v-on
, etc.
How does Vue.js handle events?
Vue.js provides the v-on
directive to listen to DOM events and run some JavaScript when they’re triggered. It can be used to call a method or to inline JavaScript expressions directly.
What is Vue-CLI?
Vue-CLI is a full system for rapid Vue.js development. It provides a standard build setup with a project scaffolding tool, a runtime dependency (vue), a build tool (vue-cli-service), and a project manager (vue ui). It’s highly configurable and designed to be flexible and supportive of modern web development needs.
What is Vue Router?
Vue Router is the official router for Vue.js. It deeply integrates with Vue.js core to make building Single Page Applications with Vue.js a breeze. It provides features like lazy-loading, dynamic route matching, location transition, and more.
Hathibelagal is an independent developer and blogger who loves tinkering with new frameworks, SDKs, and devices. Read his blog here.