Vue: support for `$watch`-ing any property on a vm

Created on 24 Jun 2014  路  12Comments  路  Source: vuejs/vue

I'm trying to subscribe to any data changes made against any property on the vm, not just pre-defined property names. I couldn't find any way to do it, so here's my proposal.

I made an example here: http://jsfiddle.net/BBk3j/. In the first $watch, I subscribe to changes on the foo property. The next two $watch statements would be my proposal to allow any watching for updates on any property. Either support a wildcard syntax (which I don't think is a great idea, because * is a valid property name in JS), or a better syntax that makes the string property name optional.

Most helpful comment

this is how you do it with components... Thanks to usmanhalalit

watch:{
    '$data': {
        handler:function() {
            console.log('changed')
        },
        deep:true
    }
},

My next question is how do I tell what changed?? like which variable??

When I console.log out the first argu I get the whole data object.. which makes sense but is there a way to tell what specifically changed?

All 12 comments

You can just $watch('$data', cb)

@yyx990803 thanks for the answer!

Should this be documented better? Maybe I'm still learning how Vue.js does things, but I would have never thought of that / it seems a little unintuitive. (I'm willing / eager to contribute, as I love Vue!, just asking to know if you'd accept a PR on that.)

You can submit a PR for the docs at https://github.com/vuejs/vuejs.org

In case anyone is struggling like me with this in Vue.js 1.0.x, then here's how you do that:

vm.$watch(
    '$data',
    function (newVal, oldVal) {

    },
    {
        deep: true
    }
);

How can I get which property is changing when watching $data?

It is all documented here. Very easy:
http://vuejs.org/api/#watch

@janokary The documentation does not give any hint how to know which property changed when using $data. I am able to get notify about the new and oldvalue for all property in my viewmodel but not about which property changed

as mentioned by @guitcastro this still doesn't mention how to watch an item within a list.

Say I have a list like so

``````

data: {
    items: [
        {name: 'a', quantity: 2},
        {name: 'b', quantity: 2},
        {name: 'c', quantity: 2}
    ]
}

``````

If I do a watch on this using

``````

watch: {
    'items': {
        handler: function (value, mutation) {
        },
        deep: true
    }
}

``````

How will I know what item has been mutated / changed?

This is the issue I, nor guys on my livestream can work out.

@NoelDavies I'm wondering the same. The docs say that watching an array that mutates will not even provide the new value of the entire array. So you couldn't even loop through old and new values to find differences.

http://vuejs.org/api/#vm-watch

Why do you need it? If you think in a reactive way you should't need to know which property has changed while watching the whole object/array. In case you need to perform custom logic for a specific property change you should watch that property...

@keepitreal I think the recommend way to work around this is to have a component that wraps each element in your array. The wrapper-component would then watch for mutations. Something like...

<div v-for="el in myArray">
   <wrapper-component v-bind:el.sync="el"></wrapper-component>
</div>

this is how you do it with components... Thanks to usmanhalalit

watch:{
    '$data': {
        handler:function() {
            console.log('changed')
        },
        deep:true
    }
},

My next question is how do I tell what changed?? like which variable??

When I console.log out the first argu I get the whole data object.. which makes sense but is there a way to tell what specifically changed?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fergaldoyle picture fergaldoyle  路  3Comments

bdedardel picture bdedardel  路  3Comments

wufeng87 picture wufeng87  路  3Comments

franciscolourenco picture franciscolourenco  路  3Comments

6pm picture 6pm  路  3Comments