SyntaxStudy
Sign Up
Vue.js Computed Properties with Complex Data
Vue.js Beginner 1 min read

Computed Properties with Complex Data

Computed properties shine when processing collections for display. Sorting and filtering a list for a table, aggregating statistics from an order list, grouping items by category — these transformations are clean, testable, and cached when expressed as computed properties. Because the getter runs in a reactive context, accessing any `ref.value` or `reactive` property inside registers it as a dependency automatically. For derived data used in multiple components, lift the computation into a shared composable. A composable is simply a function that uses Vue's Composition API internally and returns reactive values. The composable can own the raw data ref and expose only the derived computed properties, keeping mutation logic centralised and the consuming components thin. When a computed property chains from another computed — `displayList` depends on `sortedList` which depends on `filteredList` which depends on `rawList` — Vue intelligently tracks the full dependency graph. Only the deepest dependency that changes triggers a re-evaluation of the chain; intermediate computeds that were not invalidated serve their cache.
Example
<script setup>
import { ref, computed } from 'vue';

const orders = ref([
  { id: 1, product: 'Widget', qty: 3, price: 9.99,  status: 'shipped'  },
  { id: 2, product: 'Gadget', qty: 1, price: 49.99, status: 'pending'  },
  { id: 3, product: 'Widget', qty: 2, price: 9.99,  status: 'shipped'  },
  { id: 4, product: 'Doohic', qty: 5, price: 4.99,  status: 'cancelled'},
]);

const filterStatus = ref('shipped');
const sortKey      = ref('product');

// Chained computed chain
const filtered = computed(() =>
  orders.value.filter(o => o.status === filterStatus.value)
);

const sorted = computed(() =>
  [...filtered.value].sort((a, b) =>
    String(a[sortKey.value]).localeCompare(String(b[sortKey.value]))
  )
);

const revenue = computed(() =>
  filtered.value.reduce((sum, o) => sum + o.qty * o.price, 0)
);

const groupedByProduct = computed(() =>
  filtered.value.reduce((acc, o) => {
    acc[o.product] = (acc[o.product] ?? 0) + o.qty;
    return acc;
  }, {})
);
</script>
<template>
  <p>Revenue: ${{ revenue.toFixed(2) }}</p>
  <li v-for="o in sorted" :key="o.id">{{ o.product }}</li>
</template>