Vue.js Tutorial
Jakob Jenkov |
Vue.js is an open source JavaScript library for making single page applications (SPA). Vue.js is very lightweight, does not require any external Node modules, and in fact, does not even require NPM to install and use it. This is a big advantage for projects that do not use Node.js for the frontend or backend otherwise.
This Vue.js tutorial will cover the basics of Vue.js so you can understand how Vue.js is designed, and get your first couple of small applications off the ground.
Vue.js Popularity
Vue.js is getting really popular and is trending close behind React.js and Angular, both of which are much heavier frameworks. According to blog posts comparing the frameworks, it is precisely because Vue.js is lightweight, yet quite powerful, that Vue.js is gaining popularity. Try doing a few Google searches for "Vue.js vs. React.js" or "Vue.js vs. Angular" and see what people write.
In a way, Vue.js is similar to Riot.js. Vue.js and Riot.js are both very lightweight frameworks for creating SPAs. However, Vue.js seems like it solves a few more problems than Riot.js, and the design of Vue.js contains a bit more elaborate, it seems. That is perhaps also why Vue.js's popularity is growing, whereas Riot.js's popularity seem to have stagnated.
Vue.js Overview
Before diving into Vue.js it is useful to get an overview of the core concepts in Vue.js. I will try to give you such an overview in this section. The core of Vue.js consists of the following parts:
- The Vue instance
- Components
- Directives
Each Vue.js application starts by creating a Vue instance. The Vue instance is a JavaScript object. This object binds the Vue.js application together.
Inside a Vue.js application you can use Vue.js components. A component is a subpart of a full application. Component typically contains the application's domain logic.
The visible part of a Vue.js application is typically rendered via Vue.js directives. A Vue.js directive is like a custom HTML element you define, which can then be used inside your Vue.js application.
Installing Vue.js
To use Vue.js you must include its JavaScript file in your HTML page. You can include Vue.js in either development or production mode. In development mode you get more debug information than in production mode. Production mode thus runs more efficiently than development mode. As the names suggest, it is recommended to use Vue.js in development mode during development, and use Vue.js in production mode when your application is deployed to production.
You can download the latest development and production version of Vue.js from the Vuejs Website.
You then include them via standard script
elements.
If you want to get started quickly with Vue.js you can also just include one of the following two
script
elements in your HTML page. These script
elements include the latest version
of Vue.js in either development or production mode.
Here is the Vue.js development mode quick include:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
Here is the Vue.js production mode quick include:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
While the quick include method can get you started using Vue.js almost immediately, you should probably decide on a specific version to use in a real project. By deciding on a specific version you avoid problems that could occur when a new version is all of a sudden returned by the quick include URLs.
Creating a Vue Instance
A Vue.js application starts with a Vue
instance. Here is how you create a Vue
instance:
var app = new Vue({});
Notice the JavaScript object passed to the Vue
constructor. This JavaScript object can be given
a lot of properties that specify how the Vue
instance is to work. Therefore this object
is also called an options object.
Attaching the Vue Instance to an HTML Element
To apply the Vue
instance to your web application you need to attach the Vue
instance
to the root HTML element of your application. You attach a Vue
instance to an HTML element by
setting the ID of the HTML element as value of the el
property of the JavaScript object passed
to the Vue
instance when created. Here is an example of attaching a Vue
instance
to an HTML element:
<div id="appRoot"> </div> <script> var app2 = new Vue({ el: '#appRoot' }); </script>
Notice the el
property of the options object passed to the Vue
constructor.
The value of the el
property is a selector that tells which HTML element the Vue
instance should be attached to.
Passing Data to the Vue Instance
You can pass data to the Vue
instance by setting the data
property in the options
object passed to the Vue
constructor. Here is an example of passing data to a Vue
instance at creation:
var app2 = new Vue({ el: '#appRoot', data: { key1: "value1", key2: "value2" } });
This data can be accessed from within the HTML element the Vue
instance is attached to.
You will see examples of that later in this tutorial.
Vue registers all the properties found in the data
object in Vue.js's reactivity system.
This means that Vue.js monitors these properties for changes. When these properties change value, Vue.js detects it
and reacts to it. For instance, if any of these values are displayed inside the root HTML element
of the Vue
instance, the displayed value will be updated to match the new value.
Computed Properties
The properties passed to a Vue
instance via the data
object are passed "as is". Sometimes,
however, you may need to calculate a property value based on the raw value of a data property. You can do so via
Vue.js computed properties.
Computed properties are passed as functions inside a computed
object which is also passed to the
Vue
instance, along with the data
object. Here is an example of creating a Vue
instance with computed properties:
<div id="appRoot"> <p>Here is some text, and here is a variable '{{myVar}}' value.</p> <p>Here is the same text, but with a computed variable: '{{derived}}'</p> </div> <script> var app = new Vue({ el: '#appRoot', data : { myVar : "My Variable" }, computed: { derived: function() { return this.myVar.toLowerCase(); } } }); </script>
Notice the computed
object that contains the derived
property pointing to a JavaScript
function. This derived
function is a computed property. It converts the myVar
property
inside the data
property to lowercase.
Notice also the {{derived}}
property reference in the HTML template earlier in the the example.
This reference will insert the value of the computed property derived
in the HTML template
where the reference is located.
Vue.js HTML Templates
A Vue.js application typically needs to render HTML. In Vue.js HTML rendering is done via the Vue.js template language. The Vue.js template language consists of HTML mixed with dynamic content insertion points. Here is a Vue.js template example:
<p>Here is some text, and here is a variable {{myVar}} value.</p>
Notice the {{myVar}}
part of the above template definition. This part defines an insertion point.
At this point the value of the myVar
variable is inserted. The myVar
variable has
to exist as a field named myVar
inside the data
object passed to the Vue
instance when created. Here is a full example showing both Vue
instance creation and template
definition in connection:
<div id="appRoot"> <p>Here is some text, and here is a variable {{myVar}} value.</p> </div> <script> var app2 = new Vue({ el: '#appRoot', data : { myVar : "My Variable" } }); </script>
As you can see, the HTML template is nested inside the HTML element which the Vue
instance
is attached to.
The HTML generated from this example will look like this:
<p>Here is some text, and here is a variable My Variable value.</p>
Vue.js Template Insertion Points
A Vue.js insertion point must contain a JavaScript expression. That means, that the JavaScript inside the
{{
and }}
must consist of a JavaScript statement that are evaluated to a value.
The value resulting from evaluating the expression is what is inserted into the HTML template at the
place of the insertion point.
The {{
and }}
functions as markers of the beginning and end of insertion points.
The marker characters are not included in what is inserted by the insertion point. Only the value of
the expression inside these marker characters is inserted.
There are limits to how advanced JavaScript expressions Vue.js allows. For instance, the following statement counts as an expression:
{{myVar != null ? myVar : ""}
JavaScript will normally evaluate that statement to a value. Therefore it is considered an "expression". But the following JavaScript statements are not an expression:
if(myVar != null){ return myVar; } else { return ""; }
Control logic like that is not considered expressions.
Function calls are allowed in expressions though. For instance, this would be accepted as an expression, provided
the function beautifyText()
exists:
{{ beautifyText(myVar) }}
The result of this expression would be the result returned from the beautifyText()
function when called with myVar
as parameter.
Vue.JS Components
A Vue.JS component is a reusable HTML element you can use inside the HTML templates of your Vue.js application. To create a component you must first register it. Here is how registering a Vue.js component looks:
Vue.component('my-component', { });
The first parameter to the component()
function is the name of the component. This is also the
name of the HTML element you use in your HTML template to insert a component of this type.
You should use an all lowercase name, and it should include a hyphen (-
). That way you
avoid a lot of potential naming problems.
The second parameter to the component()
function is a JavaScript object that contains the
definition of the Vue.js component. In the example above this object is empty, but you will soon see what
examples of what you can insert into a Vue.js component definition.
Here is an example of using the my-component
Vue.js component that was registered in the previous
code example:
<my-component></my-component>
As you can see, you can use the registered component like an HTML element.
The component is not really doing anything at this point, so let's add a component template. A component template is a string of HTML which is displayed where the component is located in the HTML document. Let me first add the template to the component registration:
Vue.component('my-component', { template: '<div>Hello World, my-component!</div>' });
Now, whereever you use the <my-component></my-component>
component HTML, the above
HTML template will be inserted instead. You can use the component as many times as you want in a Vue.js application.
Component Data
A component can also have data, just like a Vue
instance. However, since a component can be used
more than one time in a Vue.js application, you cannot just include a single data
object in the
component declaration, like you do in the Vue
application declaration. If you did, all instances
of a given component would use the same data
property.
Instead, we need to provide a data
object factory. Here is how that looks:
Vue.component('my-component', { template: '<div>Hello World, my-component: {{myVar}}</div>', data: function() { return { myVar: 999}; } })
First, notice how the component template now contains the template insertion point {{myVar}}
.
This insertion point refers to the myVar
variable declared in the data object returned by
the data factory function.
Second, notice how the data
factory function returns a JavaScript object with a variable in
called myVar
. It is this variable that is inserted into the HTML template with the component
renders itself.
Here is a full example of declaring and using the above component:
<div id="appRoot"> <my-component></my-component> </div> <script> Vue.component('my-component', { template: '<div>Hello World, my-component: {{myVar}}</div>', data: function() { return { myVar: 999}; } }); var app = new Vue({ el: '#appRoot', }); </script>
The HTML rendered from this would look similar to this:
Hello World, my-component: 999
Component Computed Properties
Vue.js components can also have computed properties. You configure computed properties for a Vue.js component
just like you do for the Vue
instance itself - by including a computed
object with
functions computing the properties in the JavaScript object that defines the component. Here is an example
of adding computed properties to a Vue.js component:
<div id="appRoot"> <p>Here is some text, and here is a variable {{myVar}} value.</p> <my-component></my-component> </div> <script> Vue.component('my-component', { template: '<div>Hello World, my-component: {{myVar}} -> {{derived}}</div>', data: function() { return { myVar: 999}; }, computed: { derived: function(){ return this.myVar * 2; } } }); var app = new Vue({ el: '#appRoot', data : { myVar : "My Variable" } }); </script>
Notice how the JavaScript object defining the Vue.js component contains a computed
property with
a property called derived
which references a function. This functions takes the myVar
variable from the component's data
myVar
property and multiplies it by 2.
Notice also the {{derived}}
property reference in the component's HTML template. This reference
will insert the value of the computed property derived
at the given place in the HTML template.
Component Properties
A Vue.js component can have component properties which values can be set from where you use the component. A component property value is set via an HTML attribute in the element that represents an instance of the component. Here is an example of a component HTML element with single property value inserted:
<div id="appRoot"> <my-component title="First Component"></my-component> <my-component title="Second Component"></my-component> </div> <script> Vue.component('my-component', { template: '<div>{{title}}</div>', props : ["title"] }); var app = new Vue({ el: '#appRoot', data : { myVar : "My Variable" } }); </script>
First notice how the two <my-component></my-component>
component elements both
contain a title
attribute - each with different values.
Second, notice how the JavaScript object that defines the Vue.js component contains a props
field. This field has an array of string objects. Each string object represents the name of a property
that the Vue.js component can accept. The above example contains a single string value title
,
meaning this component only accepts the title
attribute.
Third, notice that the Vue.js component HTML template contains a reference to the title
property, via this reference: {{title}}
. This reference will insert the value of the
title property as passed from the component HTML when used
(the <my-component title="XYZ"></my-component>
). The example above uses
my-component
twice, and passes two different values (First Component
and
Second Component
) to the title
property.
Tweet | |
Jakob Jenkov |