Vue 2 methods vs watchers vs computed properties

By

Vue.js gives you methods, watchers, and computed properties. Learn when to use each one, from reacting to DOM events to deriving cached values from your data.

~~~

In a Vue 2 component you have three places to put logic: methods, computed properties, and watchers. Use methods to react to events, computed properties to derive values from your data, and watchers to run side effects when a property changes.

They overlap a bit, so let’s look at each one with an example.

When to use methods

A method is a function you call explicitly. Nothing runs until something calls it:

new Vue({
  el: '#app',
  data: {
    count: 0
  },
  methods: {
    addOne() {
      this.count = this.count + 1
    }
  }
})

In the template you wire it to an event:

<button @click="addOne">Add one</button>

When to use computed properties

A computed property is a value derived from other values:

new Vue({
  el: '#app',
  data: {
    firstName: 'Flavio',
    lastName: 'Copes'
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  }
})

In the template you use {{ fullName }} like any data property. Vue caches the result and only recomputes it when firstName or lastName change. A method called from the template runs again on every re-render instead.

When to use watchers

A watcher runs a function every time one property changes. It’s the right tool for side effects, like a network request:

new Vue({
  el: '#app',
  data: {
    query: ''
  },
  watch: {
    query(newValue, oldValue) {
      fetch('/api/search?q=' + newValue)
    }
  }
})

A common mistake

A computed property must return its value synchronously. If you put a fetch() call in a computed property, the template gets a Promise instead of the data you wanted.

When you need async work in response to a change, use a watcher. The watcher fires the request, and its callback stores the result in a data property the template can render.

Tagged: Vue.js · All topics
~~~

Related posts about vue: