I have EditTransaction component and call it 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 am sending a transaction object in it. Since this is an editor, I don't want the transaction object to be reactive. If someone closes the editor, I want the original transaction object not the modified transaction object, so if I'm correct and want to remove the proxy, I'd put it in the editor:
const form = toRaw(props.transaction)
Inside the editor template, there are some asset components whose v-model values are bound 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 that when I change the transaction name, the form object changes and also the transaction properties change. Therefore, the names in the parent data also change because transaction properties are reactive. What am I doing wrong or how can I implement a form object whose values are populated on component creation using props values and without any delegate?
P粉9501288192024-03-22 09:25:51
It's common to use props to pass an initial value to the state of a child component. This means that you "copied" the value of a prop in your local data
. It ensures that prop values are protected from unexpected changes: Read more in Vue Documentation
Here is a very simple example demonstrating 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 are trying to update some data in the form, and you don't want to change the initial information unless confirmed by a button or something. The process to solve this problem is:
this.$emit
) so that it understands the changes. P粉5739437552024-03-22 00:34:17
So I found two solutions:
const form = reactive({...props.transaction})
or
const form = Object.assign({}, props.transaction)
Both work, when I change the form value it doesn't change the props.