computed Properties
computed lets you define a value that is automatically derived from reactive state. When the state it depends on changes, the computed value updates automatically. When nothing changed, it returns the cached result.
Basic usage
Section titled “Basic usage”<script setup lang="ts">import { ref, computed } from 'vue'
const people = ref([ { id: '1', name: 'Alice', parentIds: [] }, { id: '2', name: 'Bob', parentIds: ['1'] }, { id: '3', name: 'Carol', parentIds: ['1'] },])
const focusId = ref('1')
const children = computed(() => people.value.filter(p => p.parentIds.includes(focusId.value)))</script>
<template> <p>Children of focus person: {{ children.length }}</p> <ul> <li v-for="child in children" :key="child.id">{{ child.name }}</li> </ul></template>children is a computed ref. Vue tracks which reactive values it reads — people.value and focusId.value — and re-computes automatically when either changes. In the template, children is auto-unwrapped just like a regular ref.
Computed vs methods
Section titled “Computed vs methods”You could achieve the same result with a method:
function getChildren() { return people.value.filter(p => p.parentIds.includes(focusId.value))}The difference: computed values are cached. Vue only re-runs the getter when a dependency changes. If children is used in three places in the template, Vue runs the filter once and returns the cached result for the other two uses.
A method called three times in the template runs the filter three times on every render.
Use computed for derived values. Use methods for actions and event handlers.
Computed in FamilyTree’s store
Section titled “Computed in FamilyTree’s store”FamilyTree’s familyStore.ts uses computed properties extensively to derive relationships from the flat people array:
const focusPerson = computed<Person | undefined>(() => people.value.find(p => p.id === focusPersonId.value))
const parents = computed<Person[]>(() => focusPerson.value ? people.value.filter(p => (focusPerson.value!.parentIds ?? []).includes(p.id)) : [])
const currentSpouse = computed<Person | undefined>(() => // finds the person in the spouses array without a divorceDate)None of this data is stored redundantly. Parents, children, spouses — all derived on demand from the single source of truth: the people array.
Writable computed
Section titled “Writable computed”A computed can have both a getter and a setter:
const fullName = computed({ get: () => `${firstName.value} ${lastName.value}`, set: (value: string) => { const [first, last] = value.split(' ') firstName.value = first lastName.value = last },})This is used occasionally for v-model on composed values. In most cases you only need the getter form.
Exercise
Section titled “Exercise”- Create a component with a
ref<string[]>array of names. - Add a computed
sortedNamesthat returns the array sorted alphabetically. - Add a computed
nameCountthat returns the number of names. - Display both in the template. Add a button that pushes a new name to the array. Confirm both computed values update automatically.
computed(() => expression)returns a reactive ref whose value is derived from other reactive state.- Vue caches the result and only re-runs the getter when dependencies change.
- Use
computedfor derived values; use methods for event handlers and actions. - Computed values are auto-unwrapped in templates — no
.valueneeded.