Search code examples
vue.jsvuetify.jsmutationprop

Unexpected mutation of Prop


I am passing an apiStepNumber prop from the parent component to the child component and using it in the child component as a v-model value

NOTE: Code Snippets will not work. Please avoid running them. Snippets are for understanding purposes only

Parent Component

I am calling various APIs inside the parent component and updating the apiNumber data variable as 1 2 3.. so on at successful API calls and passing it as an apiStepNumber prop.

if(firstApiCallSuccessful) this.apiNumber = 2;

if(secondApiCallSuccessful) this.apiNumber = 3;

..so on

<child-component :apiStepNumber="apiNumber"></child-component>

Child Component

( I am using the apiStepNumber prop as v-model value and other basic calculations but getting an error as "Unexpected mutation of 'apiStepNumber' prop" at v-model="apiStepNumber" )

<script>
export default {
    props: {
        apiStepNumber: {
            type: Number,
            required: true,
            default: 1,
        },
    },
    data() {
        return {
            steps: [
                { id: 1, text: "Emailing the Link" },
                { id: 2, text: "Getting Details" },
                { id: 3, text: "Extracting Data" },
                { id: 4, text: "Validating Data" },
                { id: 5, text: "Almost there..." },
                { id: 6, text: "All Done!" },
            ],
        };
    },
}
</script>
<v-stepper v-model="apiStepNumber" vertical>
  <v-stepper-step
    v-for="(item, i) in steps"
    :key="item.id"
    :complete="apiStepNumber > i + 1"
    :step="i + 1"
    :color="apiStepNumber > i + 1 ? 'success' : 'primary'"
  >{{ item.text }}</v-stepper-step>
</v-stepper>

What I tried

  1. Saving the prop value in the local data variable inside the child component and use that local variable rather than the prop directly, but that does not meet my requirement.
  2. Tried looking at other posts on StackOverflow, on this topic but was not able to fix the issue.

Thanks in advance for your help on this.


Solution

  • As the error says, props cannot be mutated. Unless there's a need for a child to have its own state (e.g. to undo changes) it needs a parent to apply all changes to the state, this is the way two-way binding works.

    A child needs to emit an event on changes. For Vue 2, v-model convention can be followed like:

    <v-stepper
      :value="modelValue"
      @input="$emit('input', $event)"
    >
    

    apiStepNumber needs to be renamed to apiNumber the convention:

    props: {
        value: {
             ...
    

    A parent could use <child v-model="apiNumber"> to receive values from input event.