Let's talk about computed properties.
So far you've learned howVue handles its own local state, the one we put insidedata
, and how a component can handle itsprop
properties - the ones that get handed down by the parent.
However, there is a type of properties inVue which are calledComputed Properties. Let's take a look at these today.
We're going to use a clean slate today, so that we can build a clear example. Here's the code.
<html><head><title>Vue 101</title></head><body><divid="app"><age-calculator></age-calculator></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>Vue.component('age-calculator',{template:` <p> NAME has been kicking butt for X days! </p> `});constapp=newVue({el:'#app'});</script></body></html>
I've gone ahead and added the scaffolding for anage-calculator
component, right now it only outputs a<p>
tag with an X where we're going to perform some sort of calculation. I've also added the corresponding tags<age-calculator>
to thediv#app
.
If you need a refresher on basic components, take a look atPart V of this series, or better yet, nosedivethe official docs!
When a simple prop isn't enough
Before we write any code, let's talk about what we're trying to accomplish.
I want to have a component where I pass it someone's age, and it will tell us how many days they've been around to enjoy avocados. If you don't like avocados then this is where our relationship ends, have a nice life.
Let's tackle the easy tasks that we already know how to accomplish, first we need an array of people with ages so that we can loop through it and output a bunch of components. Let's add the correspondingdata
.
constapp=newVue({el:'#app',data:{people:[{name:'Mario',age:38},{name:'Luigi',age:38},{name:'Samus',age:31},{name:'Link',age:20},{name:'Marina',age:32},//Add yourself here :)]}});
Now, let's set up ourv-loop
to output anage-calculator
per each one.
<divid="app"><age-calculatorv-for="person in people":key="person.name"></age-calculator></div>
Awesome, now let's allow theage-calculator
component to receive aperson
, remember we do this with aprop
. So first, let's add this newprop
to the component.
Vue.component('age-calculator',{props:{person:{type:Object,required:true}},template:` <p> {{ person.name }} has been kicking butt for X days! </p> `});
Bonus! Before you learned that to declare the props that a component can receive, you set up an array of stringsprops: ['person']
and this is fine in most cases. But what happens if we want a bit more control?
You can also, like in this case, setprops
to be equal to anobject. Inside this object, we can create a property per each property we want to declare.
Inside the property declaration, in this caseperson
, we can set some configuration values.
type
to declare which (duh)type of data we're passing, soObject
,Array
,String
,Number
for example.
required
is aboolean that allows us to mark this property as required for the component to work.
You can also set adefault
value, but we're not going to use that here.
Next, look at the template. We are now outputting the person's name{{ person.name }}
onto the<p>
tag.
One more thing before we can actually run this in our browser though. Can you tell what we're missing?
We still need to pass the actualperson
to theage-calculator
component!
Go into the render loop and pass in our variable.
<age-calculatorv-for="person in people":person="person":key="person.name"></age-calculator>
Go ahead and run this in your browser to check that everything is working. Baby-steps!
Note Before we move on, if you're curious what setting aprop
torequired will do for you, try removing this last bit we did when we pass the person to the component and look at your dev tools in the console section.
Handy, ain't it? 👌
The actual Computed Property
Alright, enough setting up and review.
We still have one more feature to tackle inside our component, we want tocalculate the number of days each person has been alive.
Granted, it's not a very hard calculation, we just have to multiply 365 times the number of years (we're not going to go hardcore with JS Dates here). And in fact, we could go ugly and direct and put this straight into our template.
template:` <p> {{ person.name }} has been kicking butt for {{ person.age * 365 }} days! </p> `
This works, sort of. But what happens when you require more logic? A hardercomputation
, some ifs/ands/ors/whens/beers? Then you're in a real problem because you can't really put that much logic inside the template, or it's going to get unmanageable real quick.
Here's wherecomputed properties shine. Computed properties are in the end functions, that will execute a bit of code, and return a value. This value is now treated like a property, which means we can straight up use it in our template.
Let's take a look at how to set it up. First, let's add the computed wrapper to our component.
Vue.component('age-calculator',{props:{person:{type:Object,required:true}},template:` <p> {{ person.name }} has been kicking butt for {{ person.age * 365 }} days! </p> `,computed:{// Computed props go here}});
So far so good, in fact this structure is the exact same one we have been using formethods
, remember? (If you're thinking a method could also solve our problem, you're on the right track - we'll talk about this in a minute.)
Let's create a newcomputed property calleddaysAlive
, it needs to be a function, and it needs to return something.
computed:{daysAlive(){//Remember, computed props are functions in the endreturnthis.person.age*365}}
Take note that just like inmethods
we need to access theperson
prop thoughthis
, only inside the template we can use it directly! Other than that, nothing too fancy going on.
Now let's use this newdaysAlive
prop in our template.
template:` <p> {{ person.name }} has been kicking butt for {{ daysAlive }} days! </p>`,
Note that we're outputting the value of thedaysAlive
--property--, (aha moment here).Vue treats computed props as, well, props - so we can use this here as you would aprops
prop, or adata
prop.
In fact,Vue makes it so that if you would need to use this prop inside amethod
for example, you would have to access it throughthis.daysAlive
. Neat right? It ACTUALLY becomes a prop. 🤯
YAY, run it in the browser and bask in your awesomeness.
Methods vs Computed Properties
You may have noticed a lot of similarities between methods and computed props, I mean, they're basically identical at code level. However there is a CORE difference that you need to understand in order to harness them fully.
Computed properties get cached.
What this means is, in the simplest possible way to explain it, that behind the scenesVue will "read" your code and look forreactive dependencies - sodata
props andprops
props. It willwatch these properties, and whenever they change,Vue will recalculate the value of your computed property. If they don't change, it'll just use a cached/stored value.
Methods, on the other hand, are ran EVERY time - there is no caching, no code reading, no magic. They're just plain old functions.
Why does this matter? When are these functions called?
Every time your component/app re-renders (so every time a component's data change, or every time it's parent's data changes),Vue will figure out if that data is tied to acomputed property, if it's not - it won't call this function again. For regular methods however, they will be re-run every time!
For this example, where we're doing a very simple calculation for these few objects it doesn't really matter, frankly. But when you start doing some serious code weightlifting on top of a thousand components, then you're going to want to leverage this caching or your app is going to take a hit on each render cycle.
If you want to read more, here's a link to the official docs regardingcomputed properties.
Here's the complete code for today.
<html><head><title>Vue 101</title></head><body><divid="app"><age-calculatorv-for="person in people":person="person":key="person.name"></age-calculator></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>Vue.component('age-calculator',{props:{person:{type:Object,required:true}},template:` <p> {{ person.name }} has been kicking butt for {{ daysAlive }} days! </p> `,computed:{daysAlive(){returnthis.person.age*365}}});constapp=newVue({el:'#app',data:{people:[{name:'Mario',age:38},{name:'Luigi',age:38},{name:'Samus',age:31},{name:'Link',age:20}]}});</script></body></html>
That's it for today! Thanks for reading, and we'll keep on going next week withwatchers
! 🕵️♀️ 👀
Top comments(10)

- LocationAbuja, Nigeria
- WorkBack-end developer
- Joined
Never knew computed properties where cached, I have always used methods instead because I thought they were the same thing. Not anymore

- Joined
Your training, complete is. :D

- LocationBangalore
- EducationPSG college of technology
- WorkSoftware developer at Accenture
- Joined
Since computed properties are read by vue before executing them, wouldn't it make complex functions slower than using it in methods? Methods are only executed right?
Assuming my elements change everyframe..

- LocationHaarlem
- EducationBachelor of IT
- WorkWeb developer at WebConcern
- Joined
Clear and concise with a dash of humor, love it!

- Joined
Glad you enjoyed it :)

- LocationSarajevo
- WorkUI designer & developer at BPU Holdings
- Joined
Very useful, thank you!
P.S. Great style of writing and explanations.

- Joined
Thanks for reading :)
For further actions, you may consider blocking this person and/orreporting abuse