I'm developing an application form. The components tree of it:
Application
Form
Fieldset
Field
The Application component has configuration props for the Form component called formSettings
so that it passes them so:
<application-form v-bind="formSettings"/>
Next, I need to synchronize FormData with the Fieldsets.
It's important that in my case all values to sync have an object type!
To achieve it, firstly, I've decided to make a deep clone of the fieldsets configuration prop to an inner attribute of the Form, called form
, in the created hook, and additionally add a special attribute to each of them, called value
, which stores all the values of the fieldset's fields:
created() {
this.form.fieldsets = _.cloneDeepWith(this.fieldsets);
this.form.fieldsets.forEach(fieldset => {
fieldset.value = {};
fieldset.fields.forEach(field => {
fieldset.value[field.name] = field.value;
})
})
}
So that, the Form's template renders using this clone:
<vue-fieldset v-for="(fieldset, i) in fieldsets"
:key="`fieldset-${i}`"
v-model="fieldset.value"
v-bind="fieldset"/>
Next, I need to synchronize the Fieldsets value to their Fields. I tried an approach like in the Form component - to create an inner mutable attribute storing the clone of the components configuration props with their values. Using it doesn't update nested components as expected, and when I tried to change some field value in form.fieldsets
, it doesn't change anything in child components so that I declined this approach. Another approach I use is to define a computed property in the Fieldset component:
computed: {
collectedValue: {
get() {
return this.value
},
set(newValue) {
this.$emit('update:value', newValue);
}
}
}
And then - use v-model on it:
<vue-input v-for="field in fieldset.fields"
:key="field.name"
v-model="collectedValue[field.name]"
v-bind="field"/>
But it doesn't update the Fields components too.
What can I do to make nested v-model for objects work properly?