Vue.js Quick Start Guide
上QQ阅读APP看书,第一时间看更新

What exactly are these dependencies?

Consider this simple Vue app, available as a pen at this link: https://codepen.io/AjdinImsirovic/pen/qKVyry.

This is the code of the simple app:

<!--HTML-->
<div id="example">
<p>Enter owner name and the thing that is owned:
<input v-model="ownerName" placeholder="enter owner">
<input v-model="thing" placeholder="enter thing">
</p>
<span>{{ ownerName }}</span>
<span> has a </span>
<span>{{ thing }}</span>
</div>

// JS
var example = new Vue({
el: '#example',
data: {
ownerName: 'e.g Old McDonald',
thing: 'e.g cow'
},
computed: {
// a computed getter
ownerHasThing: function () {
// `this` points to the Vue instance's data option
return this.ownerName + " " + this.thing
}
}
})

This code will result in this output on the screen:

First off, we can see that there is this weird has a line of text in the view. This problem here is that we have not used our ownerHasThing computed property. In other words, these three lines in HTML are completely redundant:

<span>{{ ownerName }}</span>
<span> has a </span>
<span>{{ thing }}</span>

Also, what if we wanted to run a computed property only after both the input fields have been filled out and the focus has been moved out of the inputs or the Enter key was pressed?

This might seem like a relatively complex thing to achieve. Luckily, in Vue it is very easy.

Let's look at the updated code (also available as a pen here: https://codepen.io/AjdinImsirovic/pen/aKVjqj):

<!--HTML-->
<div id="example">
<p>Enter owner name:
<input v-model.lazy="ownerName" placeholder="enter owner">
</p>
<p>Enter thing owned:
<input v-model.lazy="thing" placeholder="enter thing">
</p>
<h1 v-if="ownerName && thing">{{ ownerHasThing }}</h1>
</div>

The JavaScript code is only slightly different:

var example = new Vue({
el: '#example',
data: {
ownerName: '',
thing: ''
},
computed: {
// a computed getter
ownerHasThing: function () {
// `this` points to the Vue instance's data option
return this.ownerName + " has a " + this.thing
}
}
})

We can conclude from this that computed properties are simply data dependencies that have some computations performed on them. In other words, ownerHasThing is a computed property, and its dependencies are ownerName and thing.

Whenever ownerName or thing are changed, the ownerHasThing computed property will update as well. 

However, the ownerHasThing will not update always, since it is cached. Contrary to this, a method will always update; that is, it will always be run, regardless of whether the data model has changed or not.

This might not seem like a very important difference, but consider a situation in which your method needs to fetch data from a third-party API or it has a lot of code to run. This might slow things down, and that's why in such cases, using computed properties is the way to go.

Before we conclude this section, let's quickly go over the code in the previous example.

In HTML, we are using v-model.lazy. The lazy modifier waits for the user to either click outside of the input or press the Enter key on their keyboard, or otherwise leave the input field (such as by pressing the Tab key). 

Still in HTML, we are also using the v-if directive, and we give it ownerName && thing. Then, we add mustache templates: {{ ownerHasThing }} . The v-if directive will wait until both ownerName and thing are updated in the data object. So, once that both inputs are filled out and no longer in focus, does the computed property update the underlying data model, and only then is the {{ ownerHasThing }} message printed on the screen.

In the next section, we'll look at how we can work with templates and components.