What is the difference between computed properties, methods and watchers in Vue?

Vue.js Reactivity Basic 1–2 Yrs2–3 Yrs Conceptual 2 min read

Quick Answer

A computed property is a cached derived value — it only recalculates when one of its reactive dependencies changes, and it's used like data. A method runs every time it's called, including on every re-render if used in the template. A watcher runs a side effect (an API call, localStorage, manual DOM work) in response to a specific value changing.

Computed properties are for values derived from state — like a full name from first and last name. They're cached, so they only recompute when a dependency actually changes, and I use them like a data property in the template. Methods aren't cached — they run every single time, so if I put a method call in the template it re-runs on every re-render. They're really for event handlers. Watchers are for side effects: when this value changes, call the API, or save to localStorage, or do something imperative. The rule of thumb is: if you're producing a value to display, use computed; if you're reacting to a change by doing something, use a watcher.

  • Computed — synchronous, pure, returns a value. fullName from firstName + lastName. Cached: reading it twice with no dependency change costs nothing. Prefer it for anything you display that's derived from state.
  • Method — no caching. Fine for event handlers (@click="save"). If you call a method in an interpolation, it re-runs on every render even if nothing relevant changed.
  • Watcher — for reacting to change with a side effect, or when you need the old and new value, or when the reaction is async. Not for computing a value you render — use computed for that.

Vue 3 — computed vs watch
import { ref, computed, watch } from 'vue'

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

// cached derived value for the template
const fullName = computed(() => `${first.value} ${last.value}`)

// side effect when a value changes
watch(fullName, (newName, oldName) => {
  localStorage.setItem('lastUser', newName)
})