Reputation: 193
I have and EditTransaction component and calling it just like this:
<edit-transaction
v-if="editableTransaction.id === transaction.id"
:key="'transaction'+transaction.id+etcount"
:class="{'bg-red-300': type === 'expense', 'bg-green-300': type === 'income'}"
:groups-prop="modelValue"
:transaction="transaction"
class="planning-transactions-item px-10 rounded-2xl w-[90%]"
@close="editableTransaction = {id: null}">
</edit-transaction>
As you can see, I'm sending a transaction object in it. Since this is an editor, I don't want the transaction object to be reactive. If somebody closes the editor, I want to have the original transaction object and not some modified one, so if I'm correct and want to remove the proxy I put this in the editor:
const form = toRaw(props.transaction)
And inside the editor template, there are some asset components which v-model values bind to the form object
<div class="flex gap-5 w-full">
<FormInput id="et-date" v-model="form.due_date" class="et-fields tw-fields w-[150px]"
placeholder="Date"
type="date"
@keyup.enter="saveChanges"></FormInput>
<FormInput id="et-name" v-model="form.name" class="et-fields tw-fields" placeholder="Name"
@keyup.enter="saveChanges"></FormInput>
<FormInput id="et-value" v-model="form.value" class="et-fields tw-fields" mask-thousand
placeholder="Value"
@keyup.enter="saveChanges"></FormInput>
</div>
The problem is when I'm changing like the transaction name for example, the form object changes but also the transaction prop. Therefore the name changes also in the parent data because the transaction prop is reactive. What am I doing wrong or how can I achieve to have a form object which values got filled up upon component create with the props value and does not have any proxies?
Upvotes: 1
Views: 8659
Reputation: 193
So I found two solutions for this:
const form = reactive({...props.transaction})
or
const form = Object.assign({}, props.transaction)
Both works and when I change the form value, it won't mutate the prop.
Upvotes: 3
Reputation: 1912
It's very common to use props to pass initial values to child component's state. This means that you "copy" the value of a prop in the local data
. It keeps the prop value safe of unexpected changes: Read more in Vue docs
This is a pretty simple example showing the above approach:
/your-child-component-vue/
export default {
props: ['initialCounter'],
data() {
return {
// counter only uses this.initialCounter as the initial value;
// it is disconnected from future prop updates.
counter: this.initialCounter
}
}
}
Now, reading your example, I see that you're trying to update some data in a form, and you don't want to change the initial information unless it's confirmed by a button or something. The flow to approach this would be:
this.$emit
) so It knows about the changes.Upvotes: 0