Implementing Computed Properties in Vue 3

Deriving State with Caching

Computed properties are used to generate values that depend on other reactive data. Unlike standard methods, they implement a caching mechanism: the value is recalculated only when its specific dependencies change. This optimization makes them superior for handling complex logic directly within templates.

Options API Example

Placing too much logic in a template can make it hard to maintain. For example, inverting a string or formatting text directly in the HTML is discouraged. The following example demonstrates how to move this logic into a computed property.

<div id="app">
  <p>Original input: {{ rawInput }}</p>
  <p>Formatted output: {{ formattedInput }}</p>
</div>

<script>
const app = {
  data() {
    return {
      rawInput: 'Vue.js'
    }
  },
  computed: {
    formattedInput() {
      // Returns the input in uppercase
      return this.rawInput.toUpperCase();
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

Composition API Usage

In the Composition API, the computed function is imported from 'vue'. It accepts a getter function and returns a read-only reactive reference. The example below calculates the total cost based on a base price and tax rate.

<template>
  <div>
    <p>Base Price: ${{ state.price }}</p>
    <p>Tax Rate: {{ state.tax }}%</p>
    <p>Total Cost: ${{ totalCost }}</p>
    <button @click="updatePrice">Increase Price</button>
  </div>
</template>

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

export default {
  setup() {
    const state = reactive({
      price: 100,
      tax: 20
    });

    // Computed property derived from state.price and state.tax
    const totalCost = computed(() => {
      const amount = state.price * (1 + state.tax / 100);
      return amount.toFixed(2);
    });

    const updatePrice = () => {
      state.price += 50;
    };

    return {
      state,
      totalCost,
      updatePrice
    };
  }
};
</script>

Comparison with Methods

It is possible to use a method to achieve the same result as a computed property. However, methods are re-evaluated every time the component re-renders, regardless of whether the data it relies on has changed. Computed properties are cached based on their dependencies, making them more performant for expensive operations.

// Method approach (called on every render)
methods: {
  calculateTotal() {
    return this.price * 1.2;
  }
}

Writable Computed Properties

By default, computed properties are read-only (getter-only). You can, however, define a setter to allow custom logic when assigning a new value to the computed property. This enables two-way binding for derived data.

const app = {
  data() {
    return {
      firstName: 'Jane',
      lastName: 'Doe'
    }
  },
  computed: {
    fullName: {
      // Getter
      get() {
        return this.firstName + ' ' + this.lastName;
      },
      // Setter
      set(newValue) {
        const names = newValue.split(' ');
        this.firstName = names[0];
        this.lastName = names[names.length - 1];
      }
    }
  }
}

const vm = Vue.createApp(app).mount('#app');

// Running the setter updates the underlying data
vm.fullName = 'Alice Smith';

console.log(vm.firstName); // "Alice"
console.log(vm.lastName);  // "Smith"

Tags: vue3 javascript Frontend Development web development

Posted on Mon, 13 Jul 2026 16:27:02 +0000 by lth2h