Computed Properties & Watchers

A computed property derives a new value from existing reactive data and automatically stays in sync with it; a watcher runs your own code as a side effect whenever a specific piece of data changes.

Computed properties: derived values that stay in sync

You could compute a derived value with a method, but a computed property is usually the better fit — it's cached, and only recalculates when one of the reactive values it reads actually changes:

JS component
Vue.createApp({
  data() {
    return { firstName: 'Priya', lastName: 'Sharma' }
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  }
})
HTML template
<p>{{ fullName }}</p>
Rendered
Priya Sharma

In the template, fullName is used exactly like a data property — no parentheses, because it isn't called like a method. If firstName changes later, fullName recomputes automatically and the template updates.

Computed vs. a method that returns the same thing

A method (fullName() called as {{ fullName() }}) would technically produce the same output, but it re-runs on every re-render of the component, no matter what caused it. A computed property only re-runs when one of its own dependencies (here, firstName or lastName) actually changes — which matters a lot once the calculation is expensive, like filtering a large list.

Watchers: reacting to a change with a side effect

Sometimes you don't want a new value — you want to do something when a value changes, like calling an API. That's what watch is for:

JS component
Vue.createApp({
  data() {
    return { searchTerm: '' }
  },
  watch: {
    searchTerm(newValue, oldValue) {
      console.log('Search changed from', oldValue, 'to', newValue)
      // e.g. call an API here
    }
  }
})
Console, after typing "vue" into a searchTerm input
Search changed from  to v
Search changed from v to vu
Search changed from vu to vue
Rule of thumb: reach for computed when you need a value derived from other data (formatting, filtering, combining) and reach for watch when you need to run a side effect — an API call, a console log, updating something outside Vue's own reactivity — in response to a change. Using a watcher just to set another piece of reactive data is almost always better expressed as a computed property instead.