Vue3 Computed Properties

Computed properties are used to dynamically calculate derived property values based on changes in other data, and they have a caching mechanism; they are only recalculated when related dependencies change.

Computed property keyword:computed。

Computed properties are very useful when handling some complex logic.

You can look at the following example of reversing a string:

Example 1

<div id="app"> {{ message.split('').reverse().join('') }} </div>

Try it »

In Example 1, the template becomes very complex and is not easy to read and understand.

Next, let's look at an example using computed properties:

Example 2

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue Test Example - Example Tutorial (example.com)</title> <script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js"></script> </head> <body> <div id="app"> <p>Original string: {{ message }}</p> <p>Computed reversed string: {{ reversedMessage }}</p> </div> <script>const app = { data() { return { message: 'EXAMPLE!!' } }, computed: { // computed property getter reversedMessage: function () { // `this` points to the vm instance return this.message.split('').reverse().join('') } } } Vue.createApp(app).mount('#app')</script> </body> </html>

Try it »

In Example 2, a computed property `reversedMessage` is declared.

The provided function will be used as the getter for the property `vm.reversedMessage`.

`vm.reversedMessage` depends on `vm.message`. When `vm.message` changes, `vm.reversedMessage` will also be updated.

Use the `computed` function to define computed properties:

Example

<template>
  <div>
    <p>Product name:{{ productName }}</p>
    <p>Product price:{{ formattedPrice }}</p>
    <button @click="increasePrice">Increase price</button>
  </div>
</template>

<script>
import { reactive, computed } from 'vue';

export default {
  setup() {
    // reactive data
    const state = reactive({
      name: 'Mobile phone',
      price: 2000
    });

    // computed property
    const productName = computed(() => {
      return`Discount ${state.name}`;
    });

    const formattedPrice = computed(() => {
      return `¥${state.price.toFixed(2)}`;
    });

    // method
    const increasePrice = () => {
      state.price += 100;
    };

    return {
      productName,
      formattedPrice,
      increasePrice
    };
  }
};
</script>

Description

computedFunction:

  • InsetupUsed in the functioncomputedUse a function to define computed properties.
  • Return the computed value through an arrow function, which automatically tracks the reactive data it depends on (statein the objectnameandprice)。

Use computed properties:

  • productNameComputed properties are derived fromstate.name, wheneverstate.namewhen changes occur,productNameit will automatically update.
  • formattedPriceComputed properties are derived fromstate.price, wheneverstate.pricewhen changes occur,formattedPriceit will automatically update.

reactive data:

  • Usereactivefunction createsstateobject, making it reactive data, allowing you to listen to changes in its properties.

Method:

  • increasePriceThe method is used to increasestate.pricethe value, and each time the button is clicked,state.pricethe value increases by 100, andformattedPricethe computed property will update accordingly.

computed vs methods

We can use `methods` to replace `computed`. The effect is the same for both, but `computed` is cached based on its dependencies, and only recalculates when related dependencies change. With `methods`, the function is always called and executed again on every re-render.

Example 3

methods: { reversedMessage2: function () { return this.message.split('').reverse().join('') } }

Try it »

It can be said that using `computed` gives better performance, but if you don't want caching, you can use the `methods` property.


computed setter

Computed properties have only a getter by default, but you can also provide a setter when needed:

Example 4

const app = { data() { return { name: 'Google', url: 'http://www.google.com' } }, computed: { site: { // getter get: function () { return this.name + ' ' + this.url }, // setter set: function (newValue) { var names = newValue.split(' ') this.name = names[0] this.url = names[names.length - 1] } } } } vm = Vue.createApp(app).mount('#app') document.write('name: ' + vm.name); document.write('<br>'); document.write('url: ' + vm.url); document.write('<br>------ Update Data ------<br>'); //When the setter is called, `vm.name` and `vm.url` will also be updated accordingly vm.site = 'Example Tutorial https://www.example.com'; document.write('name: ' + vm.name); document.write('<br>'); document.write('url: ' + vm.url);

Try it »

From the running result of the example, when runningvm.site = 'Example http://www.example.com';when,setterwill be called,vm.nameandvm.urlwill also be updated accordingly.

Other Extensions