Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Marina Mosti
Marina Mosti

Posted on • Edited on

     

Hands-on Vue.js for Beginners (Part 6)

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>
Enter fullscreen modeExit fullscreen mode

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 :)]}});
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

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>  `});
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

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>      `
Enter fullscreen modeExit fullscreen mode

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}});
Enter fullscreen modeExit fullscreen mode

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}}
Enter fullscreen modeExit fullscreen mode

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>`,
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

That's it for today! Thanks for reading, and we'll keep on going next week withwatchers! 🕵️‍♀️ 👀

Top comments(10)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
neutrino2211 profile image
Mainasara Al-amin Tsowa
Fullstack Dev, IT security nerd and IoT obsessor
  • Location
    Abuja, Nigeria
  • Work
    Back-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

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Your training, complete is. :D

CollapseExpand
 
pravinkumar95 profile image
Pravin kumar
I am a web dev with passion for building things. Always learning and enjoying🤪
  • Location
    Bangalore
  • Education
    PSG college of technology
  • Work
    Software developer at Accenture
  • Joined
• Edited on• Edited

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..

CollapseExpand
 
namstel profile image
Namstel
I'm a web developer and father from The Netherlands. I mostly do Frontend Web development, but I'm also known to dabble in PHP, MySQL and AWS. I'm interested in learning Vue and NodeJS.
  • Location
    Haarlem
  • Education
    Bachelor of IT
  • Work
    Web developer at WebConcern
  • Joined

Clear and concise with a dash of humor, love it!

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Glad you enjoyed it :)

CollapseExpand
 
dsiss profile image
DS-ISS
  • Joined

Hi Marina,
Why do we not need a data() in the component like last lesson here?

CollapseExpand
 
dsiss profile image
DS-ISS
  • Joined

I think I got it. Because we are not changing anything in "person" here.

CollapseExpand
 
neehad profile image
Nihad Obralic
UI designer & developer
  • Location
    Sarajevo
  • Work
    UI designer & developer at BPU Holdings
  • Joined

Very useful, thank you!

P.S. Great style of writing and explanations.

CollapseExpand
 
ericstolzervim profile image
Eric Stolzervim
  • Joined

Useful and enjoyable, thank you.

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Thanks for reading :)

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

More fromMarina Mosti

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp