81

I have a component with the following hash

{ 
  computed: { 
    isUserID: { 
      get: function(){
         return this.userId? 
      } 
  }
}

Should I be watching isUserID or userId for changes? Can you watch computed properties?

Saurabh
  • 71,488
  • 40
  • 181
  • 244
Kendall
  • 5,065
  • 10
  • 45
  • 70
  • 1
    It will be really helpful to answer if you can elaborate what you are trying to do. Here when getting you are getting `this.ID` while setting `this.userId`, I am not sure how will this work. – Saurabh Dec 10 '16 at 03:26
  • @saurabh I was trying to set a data property either by route params or component "props" since I can't do both I was thinking of just using a computed property and watch it. But what i really wanted to know was can you watch a computed property? – Kendall Dec 15 '16 at 13:28

3 Answers3

143

Yes, you can setup watcher on computed property, see the fiddle.

Following is the code to set watch on computed property:

const demo = new Vue({
    el: '#demo',

    data() {
        return {
            age: ''
        };
    },

    computed: {
        doubleAge() {
            return 2 * this.age;
        }
    },

    watch: {
        doubleAge(newValue) {
            alert(`yes, computed property changed: ${newValue}`);
        }
    }
});
tony19
  • 125,647
  • 18
  • 229
  • 307
Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • 6
    Ok, I'll try this again sometimes I am not able to get the events of the computed property so I have to end up using a data property instead which is usually a duplicate of a computed property. Is there any reason why a computed property fail triggering a watch event? – Kendall Dec 15 '16 at 14:05
  • 1
    @Kendall I am not sure why that will happen, if you can put relevant code where it is not working, than someone might point out some caveat or bug. – Saurabh Dec 15 '16 at 14:52
  • I eventually re worked the code to compensate. Will try to upload the original code when I get through with some other stuff – Kendall Dec 15 '16 at 15:16
  • 5
    @Kendall I met the same issues, the change of computed not trigger the watch handler, do you have any progress on this? – a.l. Jun 28 '18 at 08:33
  • 2
    @Kendall It seems like once an error was thrown in the computed function, then it won't trigger the watcher anymore, plz see the fiddle http://jsfiddle.net/j7pLbtdz/ – a.l. Jul 02 '18 at 02:10
  • Should be noted there are quite few instances which will not trigger a reaction. https://vuejs.org/v2/guide/reactivity.html -- I had to use `Vue.set`/`this.$set`. – Damien Roche Jul 23 '18 at 18:16
  • 5
    I have only had issues watching a computed property when it contained an object. Then I had to do a deep watch: `watch:{ myComputedProperty : { handler(newVal){ //do something when change happens}, deep: true}}` – Cindy Conway Nov 06 '18 at 14:18
  • @CindyConway: there is a case where not even a deep watcher does work, namely when the computed property returns different objects. – henon Sep 17 '20 at 10:01
  • The watch doesn't trigger for the initialization (on page load). To fix this, you have to add `immediate: true` as explained [here](https://forum.vuejs.org/t/watchers-not-triggered-on-initialization/12475/3) – famzah Nov 13 '20 at 04:36
  • @a.l. I was having that exact problem. I'm so glad I found your comment! Avoiding an error within the handler solved the issue of the watcher of a computed property not watching. – rubebop Jan 13 '22 at 12:08
7
computed: {
  name: {
    get: function(){
      return this.name;
    }
  }
},
watch: {
  name: function(){
    console.log('changed');
  }
}

This way we can watch over the computed property if it is changed we get notified on the console.

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104
David William
  • 101
  • 2
  • 5
5

Here's how you do it in Vue 3 with Composition API:

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

  const variable = ref(1)

  const computedProperty = computed(() => {
    return variable.value * 2
  })

  watch(computedProperty, (newValue, oldValue) => {
    console.log('computedProperty was ' + oldValue + '. Now it is ' + newValue + '.')
  })
</script>

<template>
  <button @click="variable++">Click me</button>
</template>
Ilyich
  • 4,966
  • 3
  • 39
  • 27