Consider following trivial app:
<div id="app">
<counters :counter1="counter1" :counter2="counter2">
</counters>
<button @click="onClick">Click Here</button>
</div>
JS:
Vue.component('counters', {
template: '<h1>{{counter1.count}} {{counter2.count}}</h1>',
//template: '<h1>{{count1}} {{count2}}</h1>',
props: {
'counter1': {
type: Object
},
'counter2': {
type: Object
}
},
data: function() {
return {
'count1': 0,
'count2': 0,
}
},
watch: {
counter1: function(n, o) {
console.log(JSON.stringify(n));
this.count1 = n.count;
},
counter2: function(n, o) {
console.log(JSON.stringify(n));
this.count2 = n.count;
}
}
});
var vm = new Vue({
el: '#app',
data: {
counter1: {
count: 0
},
counter2: {
count: 0
}
},
methods: {
onClick: function() {
this.counter1.count++;
this.counter2.count++;
}
}
});
"counters" expects two props counter1 and counter2 , both objects. The properties counter1.count and counter2.count are used directly in template. On clicking the button both counters are incremented by one. This works flawlessly as can be seen here: jsfiddle
However I wanted to use "watch" for updating the counters. So I defined reactive properties count1 and count2 and updated them whenever counter1 and counter2 changed. For some reason this does not work. I was under impression both approaches should yield the same result although using watch is less efficient. But probably I am missing something here. Can you explain?
If you want to watch for changes on an object you will need to use a deep watcher
:
watch: {
counter1: {
handler(n, o) {
this.count1 = n.count;
},
deep: true
},
counter2: {
handler(n, o) {
this.count2 = n.count;
},
deep: true
}
}
Here's the JSFiddle: https://jsfiddle.net/osyam658/
Alternatively you may watch the object property itself, by wrapping the property name in quotes in the watcher:
watch: {
'counter1.count': function(n, o) {
this.count1 = n;
},
'counter2.count': function(n, o) {
this.count2 = n;
}
}
Here's the JSFiddle for that: https://jsfiddle.net/b7drpy7j/
You need to setup up a deep watcher to observe changes nested inside objects as follows:
watch: {
counter1: {
handler: function(n, o) {
console.log(JSON.stringify(n));
this.count1 = n.count;
},
deep: true
},
counter2:
handler: function(n, o) {
console.log(JSON.stringify(n));
this.count2 = n.count;
},
deep: true
}
}
Here is the updated fiddle
Reference: deep
option for vm.$watch()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With