Computed properties are used to dynamically calculate derived property values based on changes in other data, and they feature a caching mechanism. They only recalculate when their related dependencies change.
Computed property keyword: `computed`.
Computed properties are very useful when handling complex logic.
Let's look at the following example of reversing a string:
## Example 1
{{ message.split('').reverse().join('') }}
[Try it Β»](#)
In Example 1, the template becomes quite complex and is not easy to read or understand.
Next, let's look at an example using a computed property:
## Example 2
Original string: {{ message }}
Reversed string (computed): {{ reversedMessage }}
const app = { data() { return { message: '!!' } }, computed: { // Getter for the computed property reversedMessage: function () { // `this` refers to the vm instance return this.message.split('').reverse().join('') } } } Vue.createApp(app).mount('#app')
[Try it Β»](#)
In Example 2, a computed property `reversedMessage` is declared.
The provided function will serve as the getter for the property `vm.reversedMessage`.
`vm.reversedMessage` depends on `vm.message`. When `vm.message` changes, `vm.reversedMessage` will also update.
Use the `computed` function to define a computed property:
## Example
Product Name: {{ productName }}
Product Price: {{ formattedPrice }}
import{ reactive, computed } from 'vue';
export default{
setup(){
// Reactive data
const state = reactive({
name:'Phone',
price:2000
});
// Computed properties
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
};
}
};
### Explanation
**`computed` function**:
* Use the `computed` function within the `setup` function to define computed properties.
* The computed value is returned via an arrow function, which automatically tracks the reactive data it depends on (`name` and `price` in the `state` object).
**Using computed properties**:
* The `productName` computed property is derived from `state.name`. Whenever `state.name` changes, `productName` updates automatically.
* The `formattedPrice` computed property is derived from `state.price`. Whenever `state.price` changes, `formattedPrice` updates automatically.
**Reactive data**:
* Use the `reactive` function to create the `state` object, making it reactive data so its property changes can be watched.
**Method**:
* The `increasePrice` method is used to increase the value of `state.price`. Each time the button is clicked, `state.price` increases by 100, and the `formattedPrice` computed property updates accordingly.
* * *
## computed vs methods
We can use methods to replace computed properties. The effect is the same, but computed properties are based on dependency caching and only re-evaluate when related dependencies change. When using methods, the function will always be re-invoked and executed during re-rendering.
## Example 3
methods: {reversedMessage2: function(){return this.message.split('').reverse().join('')}}
[Try it Β»](#)
It can be said that using computed properties offers 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: {get: function(){return this.name + '' + this.url}, set: function(newValue){var names = newValue.split('')this.name = namesthis.url = names[names.length - 1]}}}}vm = Vue.createApp(app).mount('#app')document.write('name: ' + vm.name); document.write(' '); document.write('url: ' + vm.url); document.write(' ------ Update Data ------ '); vm.site = ' '; document.write('name: ' + vm.name); document.write(' '); document.write('url: ' + vm.url);
[Try it Β»](#)
From the example's output, when running `vm.site = ' ';`, the **setter** is called, and **vm.name** and **vm.url** are also updated accordingly.
!(#)