ofey
ofey

Reputation: 3347

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

Upvotes: 33

Views: 21237

Answers (2)

pxeba
pxeba

Reputation: 1806

Vue Watchers

Using deep tag is a simpler option but be careful with lists with many objects. It is not very optimized

watch: {
    colours: {
      // This will let Vue know to look inside the array
      deep: true,

      // We have to move our method to a handler field
      handler()
        console.log('The list of colours has changed!');
      }
    }
  }

Upvotes: 1

Andrei Savin
Andrei Savin

Reputation: 2484

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>

Upvotes: 44

Related Questions