Search code examples
vue.jsemit

Can't pass checked value to parent component from custom checkbox component


In my custom checkbox component, I'm trying to pass the value of the checkbox form field to my parent component:

<template>
  <div class="custom-checkbox">
    <div :class="{ 'bg-white': value }">
      <input
        :id="checkboxId"
        type="checkbox"
        :checked="value"
        v-model="value"
        @change="$emit('input', $event.target.checked)"
      />
    </div>

    <label :for="checkboxId">
      <slot />
    </label>
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: Boolean,
      default: false
    },
    checkboxId: {
      type: String,
      default: "checkbox-1"
    }
  }
};
</script>

Getting this error:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"

I tried to add:

data() {
  return {
    checkedValue: this.value
  };
}

... then replace v-model="value" with v-model="checkedValue" but the checkbox doesn't check anymore and I still don't get the value of it in parent component.

Any suggestion?


Solution

  • It's because you are still directly mutating value, it does not matter if you catch the @change event or not.

    Try creating a computed component with a getter/setter in your child component.

    computed: {
        checked: {
            get() {
                return this.value;
            },
            set(value) {
                this.$emit("input", value);
            }
        }
    }
    

    Use checked as your checkbox v-model. No need to bind anything to :checked, only v-model will suffice.

    You can pass the value using v-model to this component in the parent.

    For reference: https://v2.vuejs.org/v2/guide/forms.html