user9875
user9875

Reputation: 133

Change Event Only fires once in a checkbox input

I have a checkbox component where I am emitting an event to the parent component. In the parent component I want to do something based on whether the checkbox is checked or not but it's only firing once

Checkbox component:

<template>
  <input
     type="checkbox"
     :checked="ischecked"
     @change="$emit('input', !ischecked)"
   />
    </template>

<script>
    props: {
      checked:{
         type: Boolean,
         default: false
      }
    },
    computed: {
        ischecked(){
          // Some checks with the checked prop, will return true or false
        }
    }
</script>

Parent Component

<template>
 <checkbox-component
     v-for="index in arrayOfData"
     :checked="index.checked"
     @input="test"
  />
</template>

<script>
   (...)
   methods: {
     test:{
       alert('change')
     }
   }
</script>

The alert only shows in the very first change of the state of the checkbox, how can I make it react to all of the checks/unchecks?

I tried to use v-model on the parent component but v-model ignores the first value (index.checked) and only relies on the component data and I can't put my data property equal to index.checked because it's only available inside the v-for

Upvotes: 1

Views: 314

Answers (1)

palaѕн
palaѕн

Reputation: 73916

You can use v-model on the checkbox-component but you will need to pass value as props to the child component to make it reactive and then you can bind checked property on the checkbox-component to that pass prop value and simply emit the current element checked status using $event.target.checked like:

Vue.component('checkbox-component', {
  template: `<input type="checkbox" 
      :checked="value" 
      @change="$emit(\'input\', $event.target.checked)" 
    />`,
  props: ['value']
})

new Vue({
  el: "#myApp",
  data: {
    arrayOfData: [{
      id: 1,
      checked: true
    }, {
      id: 1,
      checked: false
    }]
  },
  methods: {
    test() {
      console.log('change')
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="myApp">
  <div v-for="index in arrayOfData">
    <checkbox-component v-model="index.checked" @input="test"></checkbox-component>
    <label>  {{ index.checked }}</label>
  </div>
</div>

Upvotes: 1

Related Questions