Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to vue watch a specific property in an array of objects

I'm using vue.js 2.5.2

I have an array of objects and I'd like to watch forms[*].selected and if it changes call a function.

This is my attempt, but obviously it is not correct. I tried putting the array into a for loop to watch each object's property selected.

watch: {
   for (var i = 0; i < forms.length; i++) {
     forms[i].selected: function(){
     console.log("change made to selection");
   }
 }
},

This is the array of objects called forms[]

forms: [
        {
          day: '12',
          month: '9',
          year: '2035',
          colors: 'lightblue',//default colour in case none is chosen
          selected: true
        },
        {
          day: '28',
          month: '01',
          year: '2017',
          colors: 'lightgreen',//default colour in case none is chosen
          selected: true
        }
      ],

Any help would be greatly appreciated,

Thanks

like image 886
Shane G Avatar asked Sep 11 '18 19:09

Shane G


People also ask

How do I watch an array in Vue?

Or you could set the watcher into the vue instance like this: new Vue({ ... watch: { things: { handler: function (val, oldVal) { console. log('a thing changed') }, deep: true } }, ... })

How do I watch nested objects in Vue?

“🔥 You can watch nested values directly in @vuejs by using dot notation as a string. This avoids watching an object deeply and ignoring everything but one specific value.

How do you change one property in an array of objects?

To update an object's property in an array of objects, use the map() method to iterate over the array. On each iteration, check if the current object is the one to be updated. If it is, modify the object and return the result, otherwise return the object as is. Copied!


1 Answers

You could use a deep watcher, but a more elegant solution would be to create computed property of the data you want to watch, and watch that instead:

new Vue({    el: '#app',    data: () => ({      forms: [{          day: '12',          month: '9',          year: '2035',          colors: 'lightblue',          selected: true        },        {          day: '28',          month: '01',          year: '2017',          colors: 'lightgreen',          selected: true        }      ],    }),    computed: {      selected() {        return this.forms.map(form => form.selected)      }    },    watch: {      selected(newValue) {        console.log("change made to selection")      }    }  })
<html>    <head>    <script src="https://unpkg.com/vue/dist/vue.js"></script>  </head>    <body>      <div id="app">      <ul>        <li v-for="(form, i) in forms" :key="i">          <input type="checkbox" v-model="form.selected"> {{form.colors}}        </li>      </ul>    </div>    </body>    </html>
like image 78
Andrei Savin Avatar answered Sep 27 '22 21:09

Andrei Savin