What is Vue.js?
What is Vue.js?
Vue.js is a progressive Javascript framework which is designed to build interactive web applications. Vue is progressive because it can be used to power a single part of your big app, or you can use it to build the entire thing. Its non-intrusive approach had made Vue a very good alternative against tools like React or Angular. Now that Vue is more popular than ever, why not take 5 minutes to learn the basics of Vue development?
## Hello, Vue
The simplest Vue app would look something like this:
https://gist.github.com/kevinnio/766bb900636c45dd7191cbad3987b58a
This will render a simple span
element into the screen with the text Hello, Vue
. You can take a look at it here. Let's see how this works.
As you can see, our file is a regular HTML file. The first part of the file is the HTML template. That’s just old HTML (apart from {{ name }}
, but that will be explained later). After defining the template of our app, we include the Vue runtime script, and then create a new Vue instance.
In order to create a new Vue instance, we pass an options
object. This options
object includes an el
property and a data
object.
The el
property is a string referencing an element in our template. This is the element in which our Vue app will be encapsulated. You can think of it as the container of our Vue app. Our app can only reach things inside this element, but nothing outside of it. We set el
to '#app'
, since that's the element we want our app to contain within. By the way, you can use any CSS-valid selector to reference an element here.
The data
object is a set of keys and values that Vue uses to populate the HTML template. Whenever Vue encounters {{ something }}
, it will replace it with the value of data.something
. In our app there's a Hello, {{ name }}
inside the template, and since we passed { name: 'Vue' }
as data
, Vue replaces the placeholder with the actual value, resulting in Hello, Vue
. This is the standard way to populate a template with data.
## Conditionals
Now that we know how the most basic Vue app works, what about trying some conditionals?
https://gist.github.com/kevinnio/578719acb91e453e804d9c53f349943f
The previous code will show Hello, Vue
only if data.friend
is true
. You can open this fiddle and change friend
to false
to see what happens.
The v-if
directive is the way in which we can perform conditionals on Vue templates. It is basically an HTML attribute. Its value is interpreted by Vue as a property inside the data
object. If the condition is true, the element will render onto the screen, otherwise the element and its children will not be rendered.
We also have the v-else
directive to render something when the condition is false.
<div id="app">
<span v-if="friend">Hello again, {{ name }}</span>
<span v-else>Hey, nice to meet you!</span>
</div>
When data.friend
is false
, Vue will show Hey, nice to meet you!
instead of showing the greeting message. Please note that v-else
directives can only be used in an element immediately after an element with a v-if
directive.
There's also v-else-if
, which works as else if
or elsif
in other programming languages.
<div id="app">
<span v-if="friend">Hello again, {{ name }}</span>
<span v-else-if="name === 'Vue'">Oh, it's you again...</span>
<span v-else>Hey, nice to meet you!</span>
</div>
Now Vue will show a special message when data.friend
is false
and data.name
is 'Vue'
. This has the same restrictions as v-else
: it can only be used after an element with a v-if
directive.
You can play with the final version of this example here. Go crazy!
## Loops
Conditionals are fine, but what about loops? Vue uses the v-for
directive to create simple loops that traverse an array. Let's take a look at it while coding.
https://gist.github.com/kevinnio/b7198ca8cdd90d311adfb75abae51825
This will produce a list of friend names. Take a look at it here. Vue sees the v-for
directive in the li
element and repeats it for every element in the data.friends
array. Note the syntax friend in friends
, though. friends
is obviously referencing the array we defined in data
, while friend
is the way we can access each array item during the loop. This should be easier to understand with the next example:
https://gist.github.com/kevinnio/f2d85835c51a5e5107a272ec11b1f3a7
Now, instead of friends
being an array of strings, it is an array of objects. Notice how we use friend.name
inside of the li
element to access the name
property of each element in the array.
You can also use v-for
to iterate over the property values of an object.
https://gist.github.com/kevinnio/fead39216fca0acc9824f02153532f4a
This will render a list like this:
* Vue
* React
* Angular
You can also use v-for
with a range:
<div id="app">
<span v-for="n in 10">{{ n }}</span>
</div>
This will render something like this:
1 2 3 4 5 6 7 8 9 10
Finally, you can combine v-for
and v-if
to loop conditionally. Although it is not recommended, it can be useful in some scenarios. For example, let's say we want to print only even numbers from 1 to 10. This app will do the trick.
https://gist.github.com/kevinnio/d6d93229a68a025e170c04a613632567
This will render this on the screen:
2 4 6 8
Just keep in mind that whenever v-for
and v-if
are in the same element v-for
takes priority.
Bindings
You can also use Vue to assign values to HTML element attributes. Take a look at this example:
https://gist.github.com/kevinnio/1e97f944b3de15ad3b5cfbba02f5fa6f
Using v-bind:[attribute]="[expression]"
we ‘tell’ Vue that we want to set the attribute to whatever the JS expression resolves to. By that logic, having this in the template:
<button v-bind:disabled="disabled"></button>
produces this when data.disabled
is true
:
<button disabled></button>
and this when data.disabled
is false
:
<button></button>
Try to change the data
values of the example in this yourself fiddle and see how it works.
## Events
Ok, now that we know more about conditionals, loops, and bindings let's take a look at how to handle events. After all, Vue will not be as useful as it is without the ability to react to the user’s inputs.
Now we are building a small counter app. This app has a counter and a button that increments the count each time is clicked.
https://gist.github.com/kevinnio/983fdb8d2f096eafa3d2dfc8eba74e81
Feel free to count op forever in this fiddle. As you can see, whenever the button is clicked data.counter
is incremented by 1
. Vue notices that change and immediately updates the template, rendering the new counter
value. This is a Vue’s very cool called reactivity. You can read everything about it in the official docs.
Our app manages to increase the counter thanks to the v-on
directive. Similarly to v-bind
, this directive requires an event and an expression in order to work. We want to respond to the click
event, thus we used v-on:click
. Then, we used counter += 1
as the expression to be executed when the event occurs. v-on
can be used to respond to any DOM-valid event and its expression can be any JS-valid one, even function calls. For example, this shows an alert popup when the user clicks the button:
https://gist.github.com/kevinnio/8c4ffe5dc6facd380ce31bf0894f6030
Ok, now let's go for a slightly more complex example. This time we want the user to decide how much the counter is incremented with each click:
https://gist.github.com/kevinnio/a6177b9d4f2c39920a0f4e53ae6b0fdc
Watch it live here. Now we used the v-model
directive to bind the value of the input
element to data.increment
. This means that whenever the value of the input
element is changed, Vue will notice it and immediately change the value of increment
accordingly. If we change the input
value and then click the button, counter
it will increase as much as we want.
## Methods
By the way, the expression given to v-on:click
in the previous example can be refactored as follows:
<button v-on:click="incrementCounter()">Count up!</button>
And then change the JS to this:
new Vue({
el: '#counter-app',
data: { counter: 0, increment: 1 },
methods: {
incrementCounter() { this.counter += parseInt(this.increment) }
}
});
This is possible because we can pass a methods
property to the options
object required to create a Vue instance. Any function inside the methods
object will be accessible from the template, just like data from data
. Inside the functions, we can use this
to reference properties both in the data
object or the methods object. Check this out:
new Vue({
el: '#root-element',
data: { message: 'Hello, Vue' },
methods: {
upperCaseMessage() {
// References `data.message` using `this`.
return this.message.toUupperCase()
},
reverseUpperCaseMessage() {
// Calls `upperCaseMessage` using `this`.
return this.upperCaseMessage().split('').reverse().join();
}
}
});
Computed values
Using data
and methods
is fine, but what if we want to add a computed value into the template. We want this value to be recomputed every time something which depends on it changes. Vue has a special feature for this particular use case: computed values.
Let's start by building a product inventory that shows how much of each product we have in stock.
https://gist.github.com/kevinnio/5fd6c1e9a7424ba755770d55f8e0d0aa
Simple enough, right? You can take a look at it here. Now, let's say we want to show the total amount of items in stock. We could use a method to calculate that on each render, but we are going to use a computed value instead.
https://gist.github.com/kevinnio/bced2f0748ff7021e6f9fc0460621c6e
Now Vue will show the total amount of items at the bottom of the list. Computed values are defined inside a computed
object which we pass inside the required options
when creating a Vue instance. Please, note that computed values (or computables) are defined as functions, however, they are referenced as plain variables from inside the template. When Vue finds a reference to a variable in the template it will first try to look for a property in data
with the same name. If it does not find it there, it will look for a function with that name inside the computed
object.
The main advantages of computed values are:
* Their return values are cached, so their functions will not even be called in subsequent renders. The value will be fetched from the cache, boosting performance.
* The cached value will be dropped if any of the referenced values changes. In our example, itemTotal()
is referencing data.products
through this.products
. If the value of data.products
changes, Vue will invalidate the cache for this computed value and execute the function again in the next render. After that, Vue will cache the new value again.
To demonstrate this last point, let's add buttons to increase and decrease the number of items in the inventory.
https://gist.github.com/kevinnio/e54764aeefe1357cd621ee399cfcca55
Head over to this fiddle to see it in action. When you click any button, the amount for that item changes, as well as the total amount at the bottom of the list. Thanks, Vue!
## What is next?
Hopefully, this has been a useful introduction to Vue.js. Of course, there are more things to be covered, such as Watchers, Components, and Custom Events. If you want to learn more, I recommend you take a look at the Vue.js official docs as well as this excellent cookbook. You can also find courses all around the web in case you are interested in a more interactive way of learning. Feel free to reach out if you have any particular question by leaving a comment down below or via email.
Happy coding!