In this lesson, we’ll be covering Computed Properties. These are properties on the Vue instance that calculate a value rather than store a value.
Our first goal in this lesson is to display our
brand and our
product as one string.
Notice we’ve added a
product to be combined into one string. In other words, we want to display “Vue Mastery Socks” in our
h1 instead of just “Socks. How can we concatenate two values from our data?
Since computed properties calculate a value rather than store a value, let’s add the
computed option to our instance and create a computed property called
This is pretty straightforward. When
title is called, it will concatenate
product into a new string and return that string.
Now all we need to do is put
title within the
h1 of our page.
So instead of:
We now have:
It works! “Vue Mastery Socks” is appearing in our
We’ve taken two values from our data and computed them in such a way that we’ve created a new value. If
brand were to update in the future, let’s say to “Vue Craftery”, our computed property would not need to be refactored. It would still return the correct string: “Vue Craftery Socks”. Our computed property
title would still be using
brand, just like before, but now
brand would have a new value.
That was a pretty simple but not entirely practical example, so let’s work through a more complex usage of a computed property.
Currently, the way we are updating our image is with the
updateProduct method. We are passing our
variantImage into it, then setting the image to be whichever variant is currently hovered on.
This works fine for now, but if we want to change more than just the image based on which variant is hovered on, then we’ll need to refactor this code. So let’s do that now.
Instead of having
image in our data, let’s replace it with
selectedVariant, which we’ll initialize as 0.
Why 0? Because we’ll be setting this based on the index that we hover on. We can add index to our v-for here, like so.
Now instead of passing in the variantImage, we’ll pass in the index.
updateProduct method, we’ll pass in the index, and instead of updating this.image, we’ll update this.selectedVariant with the index of whichever variant is currently hovered on. Let’s put a console.log in here too, to make sure it’s working.
Now when we refresh and open up the console, we can see that it works. We’re logging 0 and 1 as we hover on either variant.
But notice this warning here in the console:
That’s because we deleted
image and replaced it with
selectedVariant. So let’s turn
image into a computed property.
Inside, we are returning
this.variants, which is our array of variants, and we are using our
selectedVariant, which is either 0 or 1, to target the first or second element in that array, then we’re using dot notation to target its image.
When we refresh, our image is toggling correctly like it was before, but now we’re using a computed property to handle this instead.
Now that we have refactored the
updateProduct method to update the
selectedVariant, we can access other data from the variant, such as the
variantQuantity they both now have.
Just like we did with
image, let’s remove
inStock from our data and turn it into a computed property that uses our variant’s quantities.
This is very similar to our
image computed property, we’re just targeting the
variantQuantity now rather than the
Now when we hover on the blue variant, which has a quantity of zero, inStock will evaluate to false since 0 is “falsey”, so we’ll now see Out of Stock appear.
Notice how our button is still conditionally turning gray whenever
inStock is false, just like before.
Why? Because we’re still using
inStock to bind the
disabledButton class to that button. The only difference is that now
inStock is a computed property rather than a data value.
Computed properties are cached, meaning the result is saved until its dependencies change. So when
quantity changes, the cache will be cleared and the **next time you access the value of
inStock , it will return a fresh result, and cache that result.
With that in mind, it’s more efficient to use a computed property rather than a method for an expensive operation that you don’t want to re-run every time you access it.
It is also important to remember that you should not be mutating your data model from within a computed property. You are merely computing values based on other values. Keep these functions pure.
Add a new boolean data property
onSale and create a computed property that takes
onSale and prints out a string whenever
onSale is true.