Options API computed property basic syntax
In the Options API, computed properties are defined in a computed object. A simple computed getter that does not take arguments returns a value based on reactive data. Example: computed: { publishedBooksMessage() { return this.author.books.length > 0 ? 'Yes' : 'No' } }
Computed properties reduce template bloat
In-template expressions should be used only for simple operations. Complex logic in templates makes them bloated and hard to maintain. Computed properties should be used for complex logic that includes reactive data.
Non-reactive values in computed properties will not update
If a computed property accesses a non-reactive value like Date.now(), it will never update because Date.now() is not a reactive dependency. The computed property will only re-evaluate when its reactive dependencies change.
Composition API computed property basic syntax
In the Composition API, the computed() function is used to create a computed property. It expects a getter function and returns a computed ref. Example: const publishedBooksMessage = computed(() => { return author.books.length > 0 ? 'Yes' : 'No' })
Computed refs are auto-unwrapped in templates
In the Composition API, computed refs are auto-unwrapped in templates. You can reference them without .value in template expressions, although you need to use .value to access the computed result in script code.
Writable computed property Options API syntax
Computed properties are getter-only by default. To create a writable computed property in the Options API, provide both a getter and a setter: computed: { fullName: { get() { return this.firstName + ' ' + this.lastName }, set(newValue) { [this.firstName, this.lastName] = newValue.split(' ') } } }
Writable computed property Composition API syntax
To create a writable computed property in the Composition API, pass an object with get and set methods to computed(): const fullName = computed({ get() { return firstName.value + ' ' + lastName.value }, set(newValue) { [firstName.value, lastName.value] = newValue.split(' ') } })
Computed property getter side effects are not allowed
Computed getter functions should only perform pure computation and be free of side effects. Do not mutate other state, make async requests, or mutate the DOM inside a computed getter. Think of a computed property as declaratively describing how to derive a value based on other values - its only responsibility should be computing and returning that value.
Computed return value should not be mutated
The returned value from a computed property is derived state that should be treated as read-only. A computed return value should never be mutated. Instead, update the source state it depends on to trigger new computations.
Getting previous value from computed property (Vue 3.4+)
In Vue 3.4+, you can access the previous value returned by a computed property. In the Options API, it is accessed as the second argument of the getter. In the Composition API, it is accessed as the first argument of the getter. This works for both simple getters and writable computed properties with separate get and set methods.
Options API computed previous value example
Example of accessing previous value in Options API: computed: { alwaysSmall(_, previous) { if (this.count <= 3) { return this.count } return previous } }
Composition API computed previous value example
Example of accessing previous value in Composition API: const alwaysSmall = computed((previous) => { if (count.value <= 3) { return count.value } return previous })
Writable computed with previous value Options API
For writable computed in Options API with previous value access: computed: { alwaysSmall: { get(_, previous) { if (this.count <= 3) { return this.count } return previous }, set(newValue) { this.count = newValue * 2 } } }
Writable computed with previous value Composition API
For writable computed in Composition API with previous value access: const alwaysSmall = computed({ get(previous) { if (count.value <= 3) { return count.value } return previous }, set(newValue) { count.value = newValue * 2 } })
Attempting to assign to read-only computed property
If you attempt to assign a new value to a read-only computed property (one with only a getter), you will receive a runtime warning.
computed type inference
computed() infers its type based on the getter's return value. For example, `const double = computed(() => count.value * 2)` infers type `ComputedRef<number>`.
Explicit computed type annotation
You can specify an explicit type for computed() via a generic argument: `const double = computed<number>(() => { /* ... */ })`. TypeScript will error if the getter does not return the specified type.
Example: Explicitly annotated computed properties in Options API
import { defineComponent } from 'vue'
export default defineComponent({
data() {
return {
message: 'Hello!'
}
},
computed: {
// explicitly annotate return type
greeting(): string {
return this.message + '!'
},
// annotating a writable computed property
greetingUppercased: {
get(): string {
return this.greeting.toUpperCase()
},
set(newValue: string) {
this.message = newValue.toUpperCase()
}
}
}
})
Explicitly annotate computed property return type in Options API
You can explicitly annotate the return type of a computed property using TypeScript syntax. For getters, add the return type after the method name: greeting(): string { return this.message + '!' }. For writable computed properties, annotate both the get() and set(newValue: string) methods separately.
Computed properties infer type from return value in Options API
A computed property automatically infers its type based on what its getter returns. TypeScript analyzes the return statement to determine the type.
computed uses reactive effects internally
The computed() function manages invalidation and re-computation using a reactive effect internally. It provides a more declarative way than watchEffect() to derive values from reactive dependencies.
Computed debugging with onTrack and onTrigger
computed() accepts a second options object with onTrack and onTrigger callbacks. onTrack is called when a reactive property or ref is tracked as a dependency. onTrigger is called when a dependency is mutated. Both receive debugger events in the same format as component debug hooks. These options only work in development mode.