A computed property is a method that returns a calculated value. It can be used in template expressions just as a normal reference. It caches the results, updating itself only when some of its dependencies are updated.

Computed properties must be implemented without side effects: don’t mutate other state, make async requests, or mutate the DOM inside a computed getter.

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

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// a computed ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

Mutation

Computed properties are by default getter-only. If it is necessary to mutate its value, getter and setter must be configured.

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

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // Note: we are using destructuring assignment syntax here.
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
</script>

Previous Values

We can access previously used value, by setting a unique parameter in the computed arrow function.

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

const count = ref(2)

// This computed will return the value of count when it's less or equal to 3.
// When count is >=4, the last value that fulfilled our condition will be returned
// instead until count is less or equal to 3
const alwaysSmall = computed((previous) => {
  if (count.value <= 3) {
    return count.value
  }

  return previous
})

// In case getter and setter are implemented.
/*
const alwaysSmall = computed({
  get(previous) {
    if (count.value <= 3) {
      return count.value
    }

    return previous
  },
  set(newValue) {
    count.value = newValue * 2
  }
})
*/
</script>

References