I noticed that in Vue you could change object fields passed as Props, and it changes these fields in parent.
Is this a bad technique? Should it be avoided, or it may be used? What the caveats of this approach?
Example:
Parent.vue:
<script setup>
import { reactive } from 'vue';
import ChildInput from "./Child.vue";
</script>
<script>
const myObj = reactive({'val':'Default text'});
</script>
<template>
<ChildInput :passedObj="myObj" />
<div>
It's a parent input:
<input v-model="myObj.val">
</div>
</template>
Child.vue:
<script setup>
const props = defineProps({
passedObj: {
type: Object,
required: true,
},
})
const dropValue = function() {
props.passedObj.val = "Changed text";
}
</script>
<template>
<div>
<label>
It's a child input:
<input v-model="passedObj.val">
<button @click="dropValue">Change text</button>
</label>
</div>
</template>
You can check this example here.
CodePudding user response:
Shallow prop mutation is prohibited because props object is read-only.
Deep prop mutation is a bad practice that should be avoided. One reason is that this makes data flow more complicated and hard to follow, that this happened unconsciously in this case explains why this is a problem. Another possible reason is that the performance can potentially be affected because this scenario lies outside the common use, although I'm unaware of such optimization problems as of now.
The official recommendation is to use v-model
two-way binding when props need to be mutated, so the mutation happens in parent component and can be tracked through Vue events when debugging is needed. When a prop is deeply mutated, it's cloned in a child and emitted to a parent.