Reputation: 443
On this example, I change the "name
" via the method:
new Vue({
el: '#exercise',
data: {
name: 'Petr',
},
methods: {
random: function() {
return Math.random();
},
changeName: function(event) {
this.name = event.target.value;
}
}
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="exercise">
<p>VueJS is pretty cool - {{ name }}</p>
<p>{{ random() }}</p>
<div>
<input v-on:input="changeName" type="text">
</div>
</div>
But each time I call the method changeName
the other method (random
) also is called.
Why?
Upvotes: 3
Views: 491
Reputation: 135752
From Computed Properties - Computed Caching vs Methods:
In comparison, a method invocation will always run the function whenever a re-render happens.
And when does a re-render happen? When data changes.
And in your example data (i.e. name
) changes whenever you type into the <input>
(because it calls changeName
).
Check the lifecycle diagram - more specifically, the "Mounted" red ball:
Check the demo below, so you see those lifecycle events are happening (and thus the re-rendering between them):
new Vue({
el: '#exercise',
data: {
name: 'Petr',
},
beforeUpdate() {
console.log('beforeUpdate executed');
},
updated() {
console.log('updated executed');
},
methods: {
random: function() {
return Math.random();
},
changeName: function(event) {
this.name = event.target.value;
}
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="exercise">
<p>VueJS is pretty cool - {{ name }}</p>
<p>{{ random() }}</p>
<div>
<input v-on:input="changeName" type="text">
</div>
</div>
Upvotes: 1
Reputation: 85545
@acdcjunior explained it very well about this issue:
In comparison, a method invocation will always run the function whenever a re-render happens.
But what if you really want to bind the random method when you really want? Here's the solution:
Modified HTML
<div id="exercise">
<p>VueJS is pretty cool - {{ name }}</p>
<p>{{ randomNumber }}</p>
<div>
<input v-on:input="changeName" type="text">
<input type="button" @click="random" value="Generate Random Number">
</div>
</div>
In the preceding example, we are using data randomNumber
. I have added a button that holds the random
method to generate a random number when we click on it.
// modified data option:
data: {
name: 'Petr',
randomNumber: '' /* initialize randomNumber */
},
// modified random method
methods: {
random: function() {
/* Now, we return data randomNumber */
return this.randomNumber = Math.random();
},
changeName: function(event) {
this.name = event.target.value;
}
},
created() {
// we need to show random number when instance is created
this.random();
}
What the heck is happening here? The method random
should be invoked and the random number should also be generated, right?
No. The method random
isn't invoked because we've not used this method anywhere ie. not bound random()
in our template binding.
So, what it means is that, the method is only invoked (after re-render as being said) if there is the method hooked somewhere inside our template.
Upvotes: 0