Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
API Styles  ›  Capstone Project

Computed Properties

Computed Properties 14 mincomputed derives a value from reactive state and caches it, recalculating only when the state it reads changes.

Computed Properties

Shelf's header says "Finished 3 of 8" and the sidebar lists only unread books. Both are calculated from the same books array. You could write the filter directly in the template, twice, and have it rerun on every render. Or you can name the result once and let Vue remember it.

The rule

Computed derives a value, caches it, and recalculates only when its inputs change.

<script setup>
import { ref, computed } from 'vue'

const books = ref([
  { title: 'Dune', pages: 412, read: true },
  { title: 'Circe', pages: 393, read: false },
  { title: 'Piranesi', pages: 245, read: false }
])

const unread = computed(() => books.value.filter(b => !b.read))
const finishedCount = computed(() => books.value.length - unread.value.length)
</script>

<template>
  <h2>Finished {{ finishedCount }} of {{ books.length }}</h2>
  <ul>
    <li v-for="b in unread" :key="b.title">{{ b.title }}</li>
  </ul>
</template>

What each part of the rule means:

  • Derives. You pass a getter, a function that returns a value. computed returns a read-only ref, so script code reads unread.value and the template reads unread.
  • Caches. Vue records which reactive data the getter touched, here books. Until that data changes, every read returns the stored result without running the getter again.
  • Recalculates on change. Flip a book's read flag and both computeds refresh; the header and list update.

Compare a method: function unreadList() { return books.value.filter(...) } called as {{ unreadList() }} gives the same output, but runs on every re-render of the component, even when something unrelated changed.

Rules for a good getter:

  • No side effects. Do not change other state, fetch data or touch the DOM inside it. It should only calculate. Side effects belong in watchers (Lifecycle Hooks section).
  • Depend on reactive data. computed(() => Date.now()) is computed once and never changes, because Date.now() is not reactive.
  • Treat the result as read-only. To make one writable you must supply both get and set; that is rare.

The shortcut

Ask: "Is this a value I could describe as a noun, built from other state?" "Unread books", "finished count", "full title" → computed. "Save the list", "load a cover" → not a value; that is an action or a side effect.

Adding "pages left to read"Step 1 of 4
  1. Is it a noun built from state?

    Yes: the total pages of unread books.

Drills

Answer fast — trust the rule.

quick drill

What is the key advantage of computed over calling a method in the template?

quick drill

In <script setup>, how do you read the computed unread?

quick drill

Which getter breaks the rules for computed?

quick drill

Why does computed(() => Date.now()) never update?

Remember

  • computed(() => ...) returns a cached, read-only ref derived from reactive state.
  • Shortcut: a noun built from state is a computed; an action is not.
  • Trap: side effects in the getter, or depending on non-reactive values.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainComputed or method?

Shelf shows 'Finished: 3 of 8' at the top. Write it with computed and explain why computed beats a method here, and one thing a computed getter must never do.