Tutorials Logic, IN info@tutorialslogic.com

Vue Computed Properties Cached Derived Values

What are Computed Properties?

Computed properties are reactive, cached values derived from other reactive data. They automatically re-evaluate only when their dependencies change - unlike methods, which re-run on every render.

Feature Computed Method Watch
Cached Yes - only recalculates when deps change No - runs every render N/A
Returns value Yes Yes No (side effects)
Async support No Yes Yes
Best for Derived data, filtering, formatting Event handlers, actions Side effects, async ops

Computed Properties - Read-only, Writable, Performance

Computed Properties - Read-only, Writable, Performance
<template>
  <div>
    <p>Full name: {{ fullName }}</p>
    <p>Reversed: {{ reversedMessage }}</p>
    <p>Active users: {{ activeCount }}</p>

    <!-- Writable computed -->
    <input v-model="fullNameWritable" placeholder="First Last" />
    <p>First: {{ firstName }}, Last: {{ lastName }}</p>

    <!-- Computed vs method - same result, different performance -->
    <p>Computed (cached): {{ expensiveComputed }}</p>
    <p>Method (not cached): {{ expensiveMethod() }}</p>
  </div>
</template>

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

const firstName = ref('Alice')
const lastName  = ref('Smith')
const message   = ref('Hello Vue!')
const users = reactive([
  { id: 1, name: 'Alice', active: true },
  { id: 2, name: 'Bob',   active: false },
  { id: 3, name: 'Carol', active: true },
])

// Read-only computed
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
const reversedMessage = computed(() => message.value.split('').reverse().join(''))
const activeCount = computed(() => users.filter(u => u.active).length)

// Writable computed - get + set
const fullNameWritable = computed({
  get: () => `${firstName.value} ${lastName.value}`,
  set: (val) => {
    const parts = val.trim().split(' ')
    firstName.value = parts[0] || ''
    lastName.value  = parts.slice(1).join(' ') || ''
  }
})

// Expensive computation - computed caches the result
const expensiveComputed = computed(() => {
  console.log('Computing...')  // only runs when users changes
  return users.reduce((sum, u) => sum + u.name.length, 0)
})

// Method - runs on every render
function expensiveMethod() {
  console.log('Method called...')  // runs every time template re-renders
  return users.reduce((sum, u) => sum + u.name.length, 0)
}
</script>

What are Computed Properties? - HTML Example

What are Computed Properties? - HTML Example
<template>
  <div class="cart">
    <div v-for="item in cart" :key="item.id" class="cart-item">
      <span>{{ item.name }}</span>
      <input type="number" v-model.number="item.qty" min="1" />
      <span>${{ (item.price * item.qty).toFixed(2) }}</span>
      <button @click="removeItem(item.id)">Remove</button>
    </div>

    <div class="cart-summary">
      <p>Items: {{ totalItems }}</p>
      <p>Subtotal: ${{ subtotal }}</p>
      <p v-if="hasDiscount">Discount (10%): -${{ discount }}</p>
      <p><strong>Total: ${{ total }}</strong></p>
      <p v-if="freeShipping" class="success">Free shipping!</p>
      <p v-else>Add ${{ shippingThreshold - subtotal }} more for free shipping</p>
    </div>
  </div>
</template>

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

const cart = reactive([
  { id: 1, name: 'Vue T-Shirt', price: 25.00, qty: 2 },
  { id: 2, name: 'Vue Mug',     price: 15.00, qty: 1 },
  { id: 3, name: 'Vue Sticker', price: 5.00,  qty: 3 },
])

const shippingThreshold = 50

const totalItems  = computed(() => cart.reduce((sum, i) => sum + i.qty, 0))
const subtotal    = computed(() => cart.reduce((sum, i) => sum + i.price * i.qty, 0).toFixed(2))
const hasDiscount = computed(() => Number(subtotal.value) >= 100)
const discount    = computed(() => (Number(subtotal.value) * 0.1).toFixed(2))
const total       = computed(() => (Number(subtotal.value) - (hasDiscount.value ? Number(discount.value) : 0)).toFixed(2))
const freeShipping = computed(() => Number(subtotal.value) >= shippingThreshold)

function removeItem(id) {
  const idx = cart.findIndex(i => i.id === id)
  if (idx !== -1) cart.splice(idx, 1)
}
</script>

Caching Depends on Reactive Reads

Vue records reactive values read while a computed getter runs. The result is reused until one of those dependencies changes. Non-reactive values such as Date.now do not invalidate the cache, and a branch that was not read does not become a dependency for that evaluation.

Computed, Method, and Watch Solve Different Problems

Use computed for pure derived state, a method when each call should perform the calculation again, and watch for a side effect such as persistence or a request. Mutating state inside a computed getter can create feedback and makes evaluation timing difficult to predict.

Writable Computed Values Need a Reversible Contract

A writable computed property supplies get and set. The setter should translate an assigned view value into deliberate source-state updates; it should not silently discard information or trigger unrelated effects. Test both directions and invalid assignments before using it as a v-model boundary.

Before you move on

Vue Computed Properties Cached Derived Values Mastery Check

4 checks
  • Keep a computed getter pure and derive its result only from reactive dependencies.
  • Use a method for uncached work and a watcher for side effects instead of hiding either inside computed state.
  • Explain when dependency changes invalidate the cached value and when they do not.
  • Use writable computed state only when getter and setter form a clear two-way contract.

Vue JS Questions Learners Ask

A computed property tracks reactive reads that happen while its getter runs. If a value is pulled out of a reactive object into a plain variable, the getter may no longer read the reactive source. Use refs, toRefs, or access the reactive object inside the computed getter.

Use a writable computed when the value is a two-way view of other state, such as a formatted input that reads from one value and writes a normalized value back.

Computed values are cached, but they still recalculate whenever one of their tracked dependencies changes.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.