0
votes

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?

2
You don't need to set the checked value or listen to the change event if you're using v-model. What does the parent component look like? - James Coyle
Also never mutate a reference path, that's why you are getting warning - stackoverflow.com/questions/56596784/… - Satyam Pathak

2 Answers

1
votes

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://vuejs.org/v2/guide/forms.html

0
votes

For the record.

CustomCheckbox.vue

<template>
    <input type="checkbox" :checked="value" @change="$emit('input', $event.target.checked)">
</template>

<script>
export default {
    props: ["value"]
};
</script>

Parent.vue

<template>
    <div id="app">
       <custom-checkbox v-model="checked"></custom-checkbox>
    </div>
</template>

<script>
import CustomCheckbox from "./components/CustomCheckbox";

export default {
    data: {
        checked: true
    },
    components: {
        CustomCheckbox
    }
};
</script>