Vue.js is simple and powerful, and it is easy to learn. Once you understand the basics of the framework, everything will work in just the way you expect. The framework will help you to keep focused on writing the logic of your application instead of remembering a bunch of APIs that are hard to use. This article will help you learn some of the fundamental concepts in Vue.js.
Fundamental concepts
When you start a Vue application, what you need to keep in mind is your application’s logic itself. You don’t need to remember a set of APIs so that you can connect different pieces of your code. Vue.js, which is a progressive framework, provides you with an intuitive way of writing web applications, starting small and growing incrementally into a large-scale application. If you have used other frameworks before, you may wonder why they make things unnecessarily complicated. Now, let’s go through fundamental concepts in Vue.js and create a sample application. You can also access the complete code for this article at https://github.com/PacktPublishing/Building-Applications-with-Spring-5-and-Vue.js-2/tree/master/Chapter02/MessagesApp.
Creating a Vue instance
Creating a Vue
instance is the start of every Vue.js application. Typically, a Vue application
consists of two types of Vue instance—the root Vue instance and component
instances. You create the root instance with the Vue function, as follows:
new Vue({/* options */});
The options object here is where you describe
your application. Vue.js takes this object and initializes the Vue instance. Let’s
create a simple application, called the Messages App and see how to use
the options object.
This SPA has the following features:
- Add a message
- View messages list
- Delete a message
- Automatically disable the add feature under certain conditions
We will start by creating the index.html file and, from there; we will build our application incrementally. Let’s have a look at the index.html file:
1.<!DOCTYPE html>
2.<html>
3.<head><title>Messages App</title></head>
4.<body>
5.
6.https://unpkg.com/vue@2.5.13/dist/vue.js
7.
8.let vm = new Vue({
9.el: '#app'
10. });
11.
12. </body>
13. </html>
In line Now, let’s define
our data model of the application. We need an array to hold those added
messages and a string to bind to the form’s input which will accept new
messages. Here is how the We add the Besides using a
plain object as the value of the Using a function
is required when you define the data structure for a component because, in that
way, Vue.js will always create a fresh data model for the new component. If you
use a plain object to define a component’s data model, all of the
instances of that component will share the same For now, we have
only defined the data model, and we haven’t told Vue.js what to do with
the The second way is to put the template directly inside the mounting point, In line In line In line In line In line Here is how the The However, you
should not use arrow functions syntax to create methods because you will lose
access to the Vue instance via Inside the Now, let’s add a way to delete a message from the UI. Here is what we change in the template: We add a button and use We delete the
selected message from the Now, let’s add the ability to automatically disable the What if we want
to change the logic so that the Here, we can use As you can see, the As you can see,
our template becomes much easier to follow and maintain since you keep most of
the logic in the JavaScript rather than in the HTML template. For the By now, we have implemented all of the features of the Messages App. Since we didn’t use Besides the By now, you’ve
learned how to use the Now, let’s
open the Apart from
the If you found this
article interesting, you can explore Building Applications with Spring 5 and
Vue.js 2 to Become efficient in
both frontend and backend web development with Spring and Vue. With the help of
Building Applications with Spring 5 and
Vue.js 2 you’ll get to grips with
Spring 5 and Vue.js 2 as you learn how to develop a web application.5, we create a app id in the DOM. And in line 9, we mount our application to this element
by using the el property of
the options object. el is short for element, and its value can be a CSS selector
string, like the one we use here, '#app', or it can be the HTMLElement itself, document.getElementById('app'). In line 8, we assign the Vue instance to the vm variable, which is short for ViewModel.
data object appears:...
let vm = new Vue({
el: '#app',
data: {
messages: [],
newMessage: ''
}
});
...data object using object literals. As you
can see, it is quite straightforward. We give them initial values so that you
can easily tell that messages is an array and newMessage is a string. Providing initial
values for the data object properties is a good practice. It not
only helps you understand the data model better, but also makes those
properties reactive by default. data property of the options object, you can also use a function
that returns a plain object, as in the example:...
data () {
return {
messages: [],
newMessage: ''
}
}
...data object, which is not desired. For
our root Vue instance here, we are safe to use a plain object.data object.
Let’s add a template for displaying and adding messages. You can add a template
in three ways. One is to add an inline template string using the template property of the options object. It is appropriate to adopt
this approach when you create a component that doesn’t have a lot of markups. . Vue.js will parse the template inside #app and replace it with HTML generated by Vue.js. The third way is to put the template markup inside a script tag, for example, <script type="x-template" id="tmplApp">, and put '#tmplApp' as the value of the template property of the options object. We will adopt the second approach here just so we can have the template markup close to the final output. Here is how the template appears:...
5.
7.
11.
12.
14.
15. </form>
16. </div>
...
7, we use the Vue built-inv-for directive to render
the messages list. The syntax of the v-for directive is alias in source. In our code, message is alias and messages is source. We don’t need to write vm.messages in order to access the messages property. Just use the exact name
that you put in the data object. And by adding the v-for directive to the li tag, we create a v-for block inside the li tag, and that’s where thealias message will be available. You can think of
the v-for block
as being equivalent to the for-loop block in JavaScript.8, we use Mustache syntax to output the text property and createdAt property of a message object of the messages list. The createdAt property is a Date object that we add when saving a new
message. When Vue.js parses the template and interpolates a Mustache tag, for
example, {{message.text}},
it creates data binding between the output and the data. It will replace the
tag with the actual value and update the output whenever the text property has been changed. The text
interpolation also supports JavaScript expression. For example, you can make
the text property
always in lower case with {{message.text.toLowerCase()}}.11, we use another built-in directive, v-on, to attach an event listener to the
form’s submitevent.prevent is a modifier, telling Vue.js to
call event.preventDefault() so that the browser won’t actually submit the form. addMessage is a method that will be invoked
when the form’s submit event is triggered. We will create this method
shortly. You can use v-on to attach listeners to all of the normal DOM
events, for example, click and mouseover. You can also use it to listen to custom events
of Vue’s custom components in the same way. We will see how that works shortly.12, we use the built-inv-model directive to create a two-way
binding between the textarea element and newMessage property of the data object. In this way, whenever the
value of the textarea element is changed, the newMessage will be updated automatically. And
when newMessage is
changed, textarea will
be updated accordingly. This is such a nice feature that you can get the value
of the textarea element
without touching it yourself specifically. It works just as you would
imagine it should.14, we add a button with type="submit" to trigger the submit event of the form. Now, let’s create
our addMessage method
to listen to that event. We can do it by using the methods property of the options object.options object appears with the addMessage method:...
let vm = new Vue({
...
data: {
...
},
methods: {
addMessage (event) {
if (!this.newMessage) {return;}
this.messages.push({
text: this.newMessage, createdAt: new Date()});
this.newMessage = '';
}
}
});
...methods property of the options object takes an object, where you put all of your methods. And inside these methods, you have access to the properties of the data object via this, as you can see that we use this.newMessage and this.messages inside the addMessage method to access them. The method syntax we use here is ES6, but you can also use function expression, as follows:addMessage: function (event) {
// Logic goes here
}this.addMessage method, we add the new message to
the messages array
using the push() method,
and then we reset the newMessage property. Accordingly, Vue.js will clear textarea in the UI automatically. This
is the magic of two-way binding, which will be revealed soon....
<li v-for="message in messages">
{{ message.text }} - {{ message.createdAt }}
<button @click="deleteMessage(message)">X</button>
</li>
...@click, the short-hand of v-on:click, to attach the listener deleteMessage method to the click event. Instead of putting the method’s name here, we use an inline statement to pass the message object to the method. And here are the updated methods of the options object:...
let vm = new Vue({
...
methods: {
...
deleteMessage (message) {
this.messages.splice(this.messages.indexOf(message), 1)
}
}
});
...messages array using the Array.prototype.splice() method. Vue.js will detect this
change and update the DOM automatically. You don’t need to manipulate the DOM
at all.add feature. Let’s say we want to disable the Add button when there are 10 messages in the list. To do that, we can use the built-in v-bind directive to bind the Add button’s disabled attribute with the messages.length >= 10 expression. In this way, Vue.js will update the disabled attribute automatically when the length of the messages array changes. Here is the updated template:...
<form @submit.prevent="addMessage">
...
Add button is disabled when the length of
the textarea input
exceeds 50 characters? You will need to change the value of the v-bind directive to newMessage.length
> 50. What if we
want to disable the button when there are already 10 messages, or the length of newMessage exceeds 50 characters? We can change the
directive value to messages.length >= 10 ||
newMessage.length > 50. It still works. However, as you can see, the code starts to bloat and it
would become hard to maintain when you need to add more logic to
decide when the Add button should be disabled.computed properties. As the name suggests, the value of such a property is computed rather than defined as those in the data object. And Vue.js will track the dependencies of a computed property and update the property’s value when the dependencies change. Let’s add the computed property addDisabled to the options object:let vm = new Vue({
data {
...
},
computed: {
addDisabled () {
return this.messages.length >= 10 || this.newMessage.length > 50;
}
},
...
});addDisabled computed property is defined as a method of the computed object of the options object. Inside the method, you also have access to the Vue instance via this. For the v-bind directive, there is also a shorthand option, which is a colon (:). Let’s update the Add button in the template to the following:<button :disabled="addDisabled" type="submit">Add</button>v-bind directive, you can use
it to bind the HTML element’s built-in attributes, for example, class and style. You can also use it to bind a Vue’s custom
component property. We will see how that works shortly.<script type="module">, you can open index.html directly using Chrome. If you try it now, you will see something strange. Immediately after opening the file, you can see the template markups that we put inside the mounting point, v-cloak directive to the mounting point and inserting a CSS rule to hide the template markups. Vue.js will remove the v-clock directive when the generated DOM is ready. The following are the updates to the index.html file:
...
[v-cloak] {display: none;}
body > div {width: 500px; margin: 0 auto;}
textarea {width: 100%;}
ul {padding: 0 15px;}
[v-cloak] CSS rule, we add a few other rules
to style the UI a little bit, even though it is still very primitive with these
rules. Now, if you open it again in the browser, there is no flash anymore. data object, the computed object, and the methods object of the options object of a Vue instance. And you
can see that, even though the properties of these objects are defined
separately, you can access them in the same way, which is via this. Console tab
of Chrome’s Developer tools. Instead of using the input field in the UI, let’s
add a new message from the console by interacting directly with
the vm object,
which is the root Vue instance that we created and made available in the global
scope. As you can see from the following screenshot, it works as you would
expect. This is its simplicity and powerfulness:
The Messages App in Chrome data, computed, and methods properties, the options object has many other properties
that you can use to define a Vue instance.