Have you ever noticed that Vue re-executes any method you are using anywhere in your HTML code between the curly braces or with v-bind
or v-Html
Or with any non-event bound method if something is changed on the screen?
No? see the running example below.
It's true that Vue re-executes methods(non-bound) if anything on the screen changes, and that's why it's called a reactive framework, right. But suppose if you have hundreds of methods and you change something on the screen and Vue starts executing these hundred's methods, just imagine the app's performance.
let's see this example :
<template>
<div id="app">
<Div>
<span>Counter :{{ counter }}</span> <br />
<button @click='counter++'>Increase</button> </t>
<button @click='counter--'>Decrease</button>
</Div>
<p>{{ currentTime() }}</p>
</div>
</template>
<script>
import VueExample from './components/HelloWorld.vue';
export default {
data() {
return {
counter: 0,
};
},
methods: {
currentTime() {
var date = new Date();
console.log("in another method")
return date;
},
},
};
</script>
In this example, there are two buttons that increases and decreases the counter upon clicking, and there is also a code for displaying the current time
{{ <p>{{ currentTime() }}</p>}}
When you click on any of the buttons, it executes the
currentTime()
method, which we can verify by either looking at the console log or just by checking the current time at the UI counter
has nothing to do with the currentTime()
method, but still, it gets executed every time you increase or decrease the counter.
Why?
The reason is that Vue
doesn't know whether the counter
attribute is part of currentTime()
method or not, in other words, we can say Vue
is not aware of whether currentTime()
has any dependency on the counter
attribute or not, Since, it doesn't know it assumes it is the part of that method. So it executes it every time.
Check the running example here
So, how do we fix it?
Well, the solution to this issue is the "Computed Property."
A computed property is similar to other properties in Vue, but in a computed property, Vue is aware of its dependency, and it only executes it when any of its dependencies change.
So, let's fix the above code.
For this, we just need to move the currentTime()
from method section to computed
section
<template>
<div id="app">
<Div>
<span>Counter :{{ counter }}</span> <br />
<button @click='counter++'>Increase</button> </t>
<button @click='counter--'>Decrease</button>
</Div>
<p>{{ currentTime }}</p>
</div>
</template>
<script>
import VueExample from './components/HelloWorld.vue';
export default {
data() {
return {
counter: 0,
};
},
computed:{
currentTime() {
var date = new Date();
console.log("in another method")
return date;
},
},
methods: {
},
};
</script>
There is another approach to solve this using Watcher
, which I "ll discuss in my upcoming articles.