Vue Computed Properties
Computed properties let you derive and cache reactive values from your component's data instead of recalculating them inside methods or templates.
What Problem Do Computed Properties Solve
Templates should stay declarative. Putting complex logic - filtering a list, formatting a date, combining several fields - directly inline makes templates hard to read and easy to duplicate. Computed properties move that logic into a single, named property that behaves just like a data property from the template's point of view.
Declaring a Computed Property
Computed properties are defined as functions on the computed option. Inside each function, this refers to the component instance, so you can read any data, prop, or other computed property. In the template, you access the result like a plain property, without parentheses.
A basic computed property
<div id="app">
<p>Full name: {{ fullName }}</p>
<input v-model="firstName" placeholder="First name" />
<input v-model="lastName" placeholder="Last name" />
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
firstName: 'Ada',
lastName: 'Lovelace'
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
})
app.mount('#app')
</script>Computed Properties vs Methods
Both computed properties and methods can return a derived value, but they behave differently. A computed property caches its result and only re-evaluates when one of the reactive values it reads actually changes. A method has no cache at all - it re-runs its entire body every single time it is called, even from the same render, even if nothing relevant changed.
Caching in action: computed vs method
<div id="app">
<p>Filtered (computed): {{ expensiveList }}</p>
<p>Filtered (method): {{ expensiveListMethod() }}</p>
<button @click="clicks += 1">Re-render ({{ clicks }})</button>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
numbers: [3, 8, 12, 5, 20, 1],
clicks: 0
}
},
computed: {
expensiveList() {
console.log('computed: recalculating filtered list')
return this.numbers.filter(n => n > 5)
}
},
methods: {
expensiveListMethod() {
console.log('method: recalculating filtered list')
return this.numbers.filter(n => n > 5)
}
}
})
app.mount('#app')
</script>- Computed properties are defined in the computed option and accessed like plain properties, without parentheses.
- A computed property re-evaluates only when one of the reactive values read inside its getter changes.
- A method runs its full body every single time it is called, even if nothing relevant to it has changed.
- Computed properties should stay pure - given the same underlying data, they should always return the same result with no side effects.
Writable Computed Properties with get and set
A computed property can also be defined with the object form, providing both a get function and a set function. This is useful when a derived value needs to support two-way binding, such as v-model on a computed full name that writes back into separate first and last name fields.
A writable computed property
<div id="app">
<p>Full name: {{ fullName }}</p>
<input v-model="fullName" placeholder="Edit full name" />
<p>First: {{ firstName }} | Last: {{ lastName }}</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
firstName: 'Grace',
lastName: 'Hopper'
}
},
computed: {
fullName: {
get() {
return this.firstName + ' ' + this.lastName
},
set(newValue) {
const parts = newValue.split(' ')
this.firstName = parts[0] || ''
this.lastName = parts[1] || ''
}
}
}
})
app.mount('#app')
</script>Exercise: Vue Computed Properties
Why does Vue cache the result of a computed property?