iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

computed()

computed() derives a reactive value from other reactive sources. The result is cached and only recomputed when a dependency changes — the right tool for any value that’s a pure function of state.

Read-only + writable computed

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

const first = ref('Ada');
const last  = ref('Lovelace');

// 1) Read-only computed
const fullName = computed(() => `${first.value} ${last.value}`);

first.value = 'Grace';
console.log(fullName.value);    // 'Grace Lovelace'

// 2) Writable computed — getter + setter
const displayName = computed({
    get: () => fullName.value,
    set: (val) => {
        [first.value, last.value] = val.split(' ');
    },
});

displayName.value = 'Linus Torvalds';
console.log(first.value, last.value);   // Linus Torvalds

// 3) Filter / sort — cached
const users = ref([
    { id: 1, name: 'Ada', active: true },
    { id: 2, name: 'Bo',  active: false },
    { id: 3, name: 'Cy',  active: true },
]);
const query = ref('');

const activeUsers = computed(() => users.value.filter(u => u.active));
const filtered    = computed(() =>
    activeUsers.value.filter(u => u.name.toLowerCase().includes(query.value.toLowerCase()))
);

// 4) Pull from a store
import { useUserStore } from '@/stores/user';
const userStore = useUserStore();
const isAdmin = computed(() => userStore.user?.role === 'admin');

// 5) Computed inside a watcher — fine, just don't mutate in a computed
import { watch } from 'vue';
watch(filtered, (curr, prev) => {
    console.log(`now ${curr.length} matches (was ${prev.length})`);
});
</script>

<template>
    <p>Hello, {{ fullName }}!</p>
    <input v-model="displayName" />
    <input v-model="query" placeholder="Search active users" />
    <ul>
        <li v-for="u in filtered" :key="u.id">{{ u.name }}</li>
    </ul>
</template>

<!-- 6) When to prefer computed vs method -->
<!-- Method: runs EVERY render — fine for simple things -->
<p>{{ fullName() }}</p>     <!-- runs N times -->
<!-- Computed: runs once per dependency change — cached -->
<p>{{ fullName }}</p>       <!-- runs 1 time -->

<!-- 7) Don't trigger side effects in a computed -->
<!-- BAD: -->
<!-- const total = computed(() => { sendAnalytics(); return rows.value.length; }); -->
<!-- Use watch() for side effects; computed() ONLY for derived data. -->

Why it matters

computed() is memoised + reactive. Reach for it any time you’d be tempted to call a method in your template — the framework caches it for free and you keep the template declarative.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import { ref, computed } from 'vue';
const price = ref(100);
const withTax = computed(() => price.value * 1.1);
Try it Yourself »

Exercise

Derive a cached, dependency-tracked value.

const double = (() => count.value * 2)

Discussion

Loading…