Padarom Padarom - 7 months ago 174
Javascript Question

VueJS event binding in v-for

I'm displaying a list of objects with VueJS like so:

<div v-for="register in registers">
<input type="checkbox" v-model="register.isEnabled">
<input type="text" v-model="register.name" :disabled="!register.isEnabled">

<span v-if="register.saved">Saved</span>
<span v-else><a @click="save(register)">Save now</a></span>
</div>


What I'd like to do, is to watch for changes in this object's values and set the
saved
attribute to
false
. This is an exemplary version of my Vue instance:

new Vue({
el: '#app',
data: {
registers: [
{ isEnabled: true, name: 'Register 1', saved: true },
{ isEnabled: false, name: '', saved: true },
]
},
methods: {
save: function(event) {
// Save object, set saved to true
}
}
});


I've tried settings an onchange listener to the div with the
v-for
attribute:

<div v-for="register in registers" @change="onChange(register)">


However this only triggers when the first input element is changed (e.g. the checkbox).

Am I able to somehow listen to all changes made to this register object, without having to add a
@change
event to every single input? If so, how?

Answer

Am I able to somehow listen to all changes made to this register object, without having to add a @change event to every single input?

This sounds like a pretty reasonable solution actually, especially since the change event doesn't bubble.

I tried to come up with a solution using watch, but since deep watch is not an option for large arrays, it would become pretty messy.

new Vue({
    el: '#app',
    ready: function() {
        this.registers.forEach(function(register, index) {
            this.$watch('registers[' + index + ']', function(newRegister, oldRegister) {
              // Check that it wasn't the `saved` state that changed
              if (newRegister.saved === oldRegister.saved) {
                  newRegister.saved = false;
              }
            });
        });
    },
    data: {
        registers: [
            { isEnabled: true, name: 'Register 1', saved: true },
            { isEnabled: false, name: '', saved: true },
        ]
    },
    methods: {
        save: function(event) {
            // Save object, set saved to true
        }
    }
});

And then you would have to rebind all the watchers in case the registers properties change.

So you're probably easier off just using @change listeners.

Comments