I'm trying to understand how to properly watch for some prop variation. I have a parent component (.vue files) that receive data from an ajax call, put the data inside an object and use it to render some child component through a v-for directive, below a simplification of my implementation:
<template> <div> <player v-for="(item, key, index) in players" :item="item" :index="index" :key="key""> </player> </div> </template>
... then inside <script>
tag:
data(){ return { players: {} }, created(){ let self = this; this.$http.get('../serv/config/player.php').then((response) => { let pls = response.body; for (let p in pls) { self.$set(self.players, p, pls[p]); } }); }
item objects are like this:
item:{ prop: value, someOtherProp: { nestedProp: nestedValue, myArray: [{type: "a", num: 1},{type: "b" num: 6} ...] }, }
Now, inside my child "player" component I'm trying to watch for any Item's property variation and I use:
... watch:{ 'item.someOtherProp'(newVal){ //to work with changes in "myArray" }, 'item.prop'(newVal){ //to work with changes in prop } }
It works but it seems a bit tricky to me and I was wondering if this is the right way to do it. My goal is to perform some action every time prop
changes or myArray
gets new elements or some variation inside existing ones. Any suggestion will be appreciated.
Using watchers in Vue # vue file we can watch for changes in data or props by using watch . For example, the below code will watch for a change in the data element pageData , and run a function according to the value it is changed to.
You need to set deep to true when watching an array or object so that Vue knows that it should watch the nested data for changes. Join 11,067 other Vue devs and get exclusive tips and insights delivered straight to your inbox, every week.
A watcher in Vue is a special feature that allows us to observe some data and perform specific actions when it changes. It is a more generic way to observe and react to data changes in the Vue instance.
Computed props can react to changes in multiple props, whereas watched props can only watch one at a time. Computed props are cached, so they only recalculate when things change. Watched props are executed every time. Computed props are evaluated lazily, meaning they are only executed when they are needed to be used.
You can use a deep watcher for that:
watch: { item: { handler(val){ // do stuff }, deep: true } }
This will now detect any changes to the objects in the item
array and additions to the array itself (when used with Vue.set). Here's a JSFiddle: http://jsfiddle.net/je2rw3rs/
EDIT
If you don't want to watch for every change on the top level object, and just want a less awkward syntax for watching nested objects directly, you can simply watch a computed
instead:
var vm = new Vue({ el: '#app', computed: { foo() { return this.item.foo; } }, watch: { foo() { console.log('Foo Changed!'); } }, data: { item: { foo: 'foo' } } })
Here's the JSFiddle: http://jsfiddle.net/oa07r5fw/
Another good approach and one that is a bit more elegant is as follows:
watch:{ 'item.someOtherProp': function (newVal, oldVal){ //to work with changes in someOtherProp }, 'item.prop': function(newVal, oldVal){ //to work with changes in prop } }
(I learned this approach from @peerbolte in the comment here)
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