SoFunction
Updated on 2025-04-06

Analysis of the reason why child components cannot modify the Prop value transmitted by the parent component in Vue

First, let's take a look at the definition of Prop in the official Vue document:

Prop is some custom properties that you can register on components. When a value is passed to a props property, it becomes a property of that component instance. In order to pass data to a child component, we need to use the v-bind directive to bind the data to be passed on on that component.

It can be seen that Prop is a mechanism for passing data. The parent component passes data to the child component through Prop. The child component receives the data passed by the parent component through Props. These data are encapsulated into destructive objects and cannot be modified directly. The advantage of this is to ensure a one-way data flow, that is, only the parent component can update the Prop, and then the data will automatically flow to the child component, thus avoiding data confusion and unpredictability.

We can understand this concept through the following simple example. Suppose we have a parent component App and a child component Child as follows:

<!--  -->
<template>
  <div>
    <child :prop1="msg"></child>
  </div>
</template>
<script>
import Child from "./";
export default {
  components: {
    Child,
  },
  data() {
    return {
      msg: "Hello, Vue!",
    };
  },
};
</script>
<!--  -->
<template>
  <div>{{ prop1 }}</div>
</template>
<script>
export default {
  props: {
    prop1: String,
  },
};
</script>

In this example, the parent component App passes a prop1 property of string type to the child component Child via Prop. Child child component declares prop1 through the props property and uses it in the template.

Now, let's assume that the prop1 property of the parent component needs to be modified in the child component:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    {{ prop1 }}
    &lt;button @click="changeMsg"&gt;Change Message&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
  props: {
    prop1: String,
  },
  methods: {
    changeMsg() {
      this.prop1 = "Hello, world!"; // Modify the value of prop1    },
  },
};
&lt;/script&gt;

If we directly modify the value of prop1 in the child component, warnings and errors will occur during runtime. The console will have the following prompts:

 [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. 
    (found in <Root>)

This warning reminds us not to directly modify the value of Prop, because this will lead to data instability and unexpected behavior. Vue advocates one-way flow of data, and all data updates should be driven by the parent component, so the child component cannot directly modify the Prop value passed by the parent component.

So what should we do? There are several ways to solve this problem:

  • Use event triggering mechanism

  • Use Computing Properties

Method 1: Use event triggering mechanism

In Vue, child components can trigger events defined in parent components through the $emit() method. When the parent component receives an event, it can call a method to update its own state, passing a new Prop to the child component. This way, let the child component tell the parent component that the data needs to be updated, rather than modifying it directly.

Here is an example that shows how to update data in a parent component through events and methods:

&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    &lt;child :prop1="msg" @change-msg="changeMsg"&gt;&lt;/child&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
import Child from "./";
export default {
  components: {
    Child,
  },
  data() {
    return {
      msg: "Hello, Vue!",
    };
  },
  methods: {
    changeMsg(newMsg) {
       = newMsg; // Update data in parent component    },
  },
};
&lt;/script&gt;
&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    {{ prop1 }}
    &lt;button @click="changeMsg"&gt;Change Message&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
  props: {
    prop1: String,
  },
  methods: {
    changeMsg() {
      this.$emit("change-msg", "Hello, world!"); // Trigger event and pass new value    },
  },
};
&lt;/script&gt;

In this example, the changeMsg() method in child component Child triggers the change-msg event and passes a new message as a parameter to the parent component App. The changeMsg() method in the parent component App receives this parameter and updates its own state.

Method 2: Use Computational Properties

Another way to solve the problem of Prop modification is by calculating properties. A computed property is essentially a function that receives a parameter and returns a value calculated from this parameter. This value can be used in the component's template.

Here is an example showing how to use computed properties instead of directly modifying Prop:

<!--  -->
<template>
  <div>
    <child :prop1="msg"></child>
  </div>
</template>
<script>
import Child from "./";
export default {
  components: {
    Child,
  },
  data() {
    return {
      msg: "Hello, Vue!",
    };
  },
};
</script>
&lt;!--  --&gt;
&lt;template&gt;
  &lt;div&gt;
    {{ modifiedProp }}
    &lt;button @click="changeMsg"&gt;Change Message&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
  props: {
    prop1: String,
  },
  computed: {
    modifiedProp: {
      get() {
        return this.prop1;
      },
      set(newVal) {
        this.$emit("update:prop1", newVal);
      },
    },
  },
  methods: {
    changeMsg() {
       = "Hello, world!"; //Update the Prop's value using computed properties    },
  },
};
&lt;/script&gt;

In this program, we define a computed property modifiedProp, which returns the current value of prop1. When modifying the value of modifiedProp in the child component, the setter method triggers the update:prop1 event, updating the value of prop1 in the parent component.

So I'll tell you!

In Vue, the reason why a child component cannot directly modify the Prop value passed by the parent component is to maintain the unidirectional flow of data and the stability of data between components. Vue provides two ways to solve Prop modification problems: using event triggering mechanisms and using computed properties. These methods allow state updates between components through events and computed properties, thus avoiding data confusion and unpredictability.

The above is the detailed analysis of the reason why child components cannot modify the Prop value transmitted by the parent component in Vue. For more information about the reason why Vue subcomponents cannot modify Prop, please pay attention to my other related articles!