Vue.js Computed Properties

Computed properties are values that Vue calculates automatically from your data. They update on their own whenever the data they depend on changes. Computed properties keep your templates clean by moving calculation logic out of the HTML.

The Problem Computed Properties Solve

Imagine you display a shopping cart total in your template. Without computed properties, you might write the calculation directly in the template:

<!-- Template becomes cluttered with logic -->
<p>Total: ${{ (price * quantity - (price * quantity * discount / 100)).toFixed(2) }}</p>

This works but the template is hard to read. If the same calculation appears in three places, you must update all three if the formula changes. A computed property solves both problems.

Defining a Computed Property

Computed properties go in the computed option. Each computed property is a function that returns a value. Vue calls it automatically and caches the result.

<div id="app">
  <p>Total: ${{ cartTotal }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        price: 50,
        quantity: 3,
        discount: 10
      };
    },
    computed: {
      cartTotal() {
        const subtotal = this.price * this.quantity;
        const discountAmount = subtotal * this.discount / 100;
        return (subtotal - discountAmount).toFixed(2);
      }
    }
  }).mount("#app");
</script>

The template now reads {{ cartTotal }} — clean and clear. The formula lives once, inside the computed property.

Diagram: Computed Property Flow

data:
  price = 50, quantity = 3, discount = 10

computed: cartTotal()
  subtotal = 50 × 3 = 150
  discountAmount = 150 × 10 / 100 = 15
  return 150 - 15 = 135.00

Template:
  {{ cartTotal }}  →  "$135.00"

When price changes to 60:
  Vue automatically re-runs cartTotal()
  subtotal = 60 × 3 = 180
  discountAmount = 180 × 10 / 100 = 18
  return 162.00
  Template updates to "$162.00"

Computed vs Methods — The Key Difference

Both computed properties and methods can return calculated values. The critical difference is caching.

  • A computed property remembers its result. If the data it depends on has not changed, Vue returns the cached result without re-running the function.
  • A method runs every time the template re-renders, even if nothing has changed.

Diagram: Cache Comparison

Scenario: Template re-renders 5 times, but price and quantity unchanged.

Method (totalPrice()):
  Render 1 → runs calculation → returns 150
  Render 2 → runs calculation → returns 150
  Render 3 → runs calculation → returns 150
  Render 4 → runs calculation → returns 150
  Render 5 → runs calculation → returns 150
  (function called 5 times)

Computed (cartTotal):
  Render 1 → runs calculation → returns 150 → caches it
  Render 2 → data unchanged → returns cached 150
  Render 3 → data unchanged → returns cached 150
  Render 4 → data unchanged → returns cached 150
  Render 5 → data unchanged → returns cached 150
  (function called only 1 time)

Use computed properties for values derived from reactive data. Use methods when you need to pass arguments or when the action has a side effect (like saving to a database).

Multiple Computed Properties

You can define as many computed properties as needed. They can also reference each other.

<div id="app">
  <p>First Name: <input v-model="firstName"></p>
  <p>Last Name: <input v-model="lastName"></p>
  <p>Full Name: {{ fullName }}</p>
  <p>Initials: {{ initials }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        firstName: "Jane",
        lastName: "Smith"
      };
    },
    computed: {
      fullName() {
        return this.firstName + " " + this.lastName;
      },
      initials() {
        return this.firstName[0] + "." + this.lastName[0] + ".";
      }
    }
  }).mount("#app");
</script>

Diagram: Multiple Computed Properties

data: firstName = "Jane", lastName = "Smith"

fullName() → "Jane Smith"
initials()  → "J.S."

User changes firstName to "Amy":
fullName() → "Amy Smith"   (auto-updated)
initials()  → "A.S."        (auto-updated)

Computed Properties with Arrays

Computed properties shine when processing arrays — filtering, sorting, or summarizing list data.

<div id="app">
  <ul>
    <li v-for="p in expensiveProducts" :key="p.id">
      {{ p.name }} — ${{ p.price }}
    </li>
  </ul>
  <p>Average price: ${{ averagePrice }}</p>
</div>

<script>
  Vue.createApp({
    data() {
      return {
        products: [
          { id: 1, name: "Keyboard", price: 45 },
          { id: 2, name: "Monitor",  price: 320 },
          { id: 3, name: "Mouse",    price: 30 },
          { id: 4, name: "Webcam",   price: 85 }
        ]
      };
    },
    computed: {
      expensiveProducts() {
        return this.products.filter(p => p.price > 40);
      },
      averagePrice() {
        const total = this.products.reduce((sum, p) => sum + p.price, 0);
        return (total / this.products.length).toFixed(2);
      }
    }
  }).mount("#app");
</script>

Diagram: Computed Filtering

products (4 items):
  Keyboard $45  ✓ (price > 40)
  Monitor  $320 ✓ (price > 40)
  Mouse    $30  ✗ (not included)
  Webcam   $85  ✓ (price > 40)

expensiveProducts → [Keyboard, Monitor, Webcam]

averagePrice:
  total = 45 + 320 + 30 + 85 = 480
  480 / 4 = 120.00

Writable Computed Properties (Getter and Setter)

By default, computed properties are read-only. You can make them writable by providing both a get and a set function.

computed: {
  fullName: {
    get() {
      return this.firstName + " " + this.lastName;
    },
    set(newValue) {
      const parts = newValue.split(" ");
      this.firstName = parts[0];
      this.lastName = parts[1] || "";
    }
  }
}

Diagram: Getter and Setter Flow

READ (getter):
  Template reads {{ fullName }}
  → get() runs → returns "Jane Smith"

WRITE (setter):
  Something sets fullName = "Tom Hanks"
  → set("Tom Hanks") runs
  → firstName = "Tom", lastName = "Hanks"
  → getter re-runs → "Tom Hanks"

Computed Property Dependency Tracking

Vue automatically tracks which data properties a computed property reads. Only when those exact properties change does Vue recalculate the computed value.

Diagram: Dependency Tracking

computed: {
  cartTotal() {
    return this.price * this.quantity;  ← reads price, quantity
  }
}

Dependencies: [price, quantity]

price changes   →  Vue recalculates cartTotal ✓
quantity changes → Vue recalculates cartTotal ✓
discount changes → Vue does NOT recalculate cartTotal
                   (discount is not a dependency)

Summary

Computed properties are functions in the computed option that return a derived value based on reactive data. Vue caches the result and only recalculates when a dependency changes. This makes computed properties much more efficient than methods for displaying calculated values. They clean up templates, centralize logic, and update automatically. Use them for filtering lists, calculating totals, combining strings, and any value that derives from existing data.

Leave a Comment

Your email address will not be published. Required fields are marked *