Home » vue » How to make custom checkbox component Vue correctly

How to make custom checkbox component Vue correctly

Posted by: admin November 26, 2021 Leave a comment

Questions:

How I can create custom checkbox in Vue. And when checkbox is changed, he should call function.
I got errors "Cannot read property ‘id’ of undefined"
And warnings "Unhandled error during execution of native event handler "

Custom checkbox:

<template>
  <div class="filter">
    <input
        :ref="id"
        :id="id"
        type="checkbox"
        class="filter-checkbox"
        @change="$emit('do', $emit)"
    />
    <span>{{ label }}</span>
  </div>
</template>

<script>
export default {
  name: "Checkbox",
  props: {
    label: {
      type: String
    },
    isSelected: {
      type: Boolean
    },
    id: {
      type: String
    }
  },
}
</script>

How i want to use it inside my parent component:

<Checkbox
   v-for="filter of filters"
   :key="filter.id"
   :label="filter.name"
   :id="filter.id"
   v-model="filter.selected"
   @do="mutuallyExclusive(filter.id)"
/>

Answers:

Can’t repeat the issue with undefined and the unhandled errors, your need to debug that further.

But your emitting the emit function, which is strange, also on change the value will always be filter.id regardless of if it’s checked or not.

You may want to do something like:

new Vue({
  el: '#app',
  components: {
    'Checkbox': {
      template: '#checkbox-template',
      props: {
        label: {
          type: String,
          default: ''
        },
        value: {
          type: Boolean,
          default: false
        },
        id: {
          type: String,
          default: ''
        }
      }
    }
  },
  data: () => ({
    filters: [{
      id: 1,
      name: 'a',
      selected: true,
    },{
      id: 2,
      name: 'b',
      selected: false,
    }]
  }),
  methods: {
    mutuallyExclusive(value) {
      console.log(value)
    }
  }
})
<div id="app">
  <Checkbox 
    v-for="filter of filters" 
    :key="filter.id" 
    :label="filter.name" 
    :id="filter.id" 
    v-model="filter.selected" 
    @change="mutuallyExclusive" 
  />
</div>

<template id="checkbox-template">
  <div class="filter">
    <input 
      :ref="id" 
      :id="id" 
      type="checkbox" 
      class="filter-checkbox"
      :checked="value"
      @change="$emit('change', {value:$event.target.checked, id})" 
    />
    <span v-if="label">{{ label }}</span>
  </div>
</template>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>