Reputation: 4969
I'm somewhat new to Vue, and I'm having particular difficulty in passing in formData
to my individual child nodes. Ideally each child node simply updates the parent formData
object allowing me to submit the form data later on as a whole.
I've setup a JSFiddle to illustrate: https://jsfiddle.net/3nm1mrLo/
My current thinking is that I should v-bind:field="formData.name"
but that throws an error. It seems as though formData
doesn't exist in the slot based HTML.
Any pointers would be gratefully received. Thanks!
Upvotes: 3
Views: 2644
Reputation: 24265
As you rightly said, you need to use v-bind:field="formData.name"
or :field="formData.name"
.
It is not working because you have defined the main app template directly in your html, and used "content distribution" to include <example-form>
and <example-input>
.
As defined in the docs, this content-distribution (or "transclusion" if you are familiar with Angular 1.x) works fine, but the scope belongs to the main app (the root instance, because the template belongs to it).
Ref: https://v2.vuejs.org/v2/guide/components.html#Compilation-Scope
Quote:
A simple rule of thumb for component scope is:
Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.
If you are curious, try changing your main app (root instance) as follows:
new Vue({
el: '*[my-app]',
data: function() {
return {
formData: { name: 'abc', location: 'xyz'}
};
}
});
Now you will see that formData is not undefined
anymore.
But a more proper method is to include <example-input>
as part of the template of example-form
component as follows:
Vue.component('example-form', {
template: `
<div class="my-example-form">
<form><pre>{{formData}}</pre><slot></slot></form>
<example-input :field="formData.name"></example-input>
<example-input :field="formData.location"></example-input>
</div>
`,
data: function() {
return {
formData: { name: '', location: ''}
};
}
});
Now it will bind to the right formData
as you would expect.
But this will still not work for you because props
is a one-way binding only. The child component (example-input
) will get the value, but will not pass the data changes back to parent component (example-form
)
For child to pass data back to parent, the right way is to use $emit
as explained in this question: Updating parent data via child component?
If you want to have an <example-input>
component to work as form elements, here is a related answer which works like what you expect: https://stackoverflow.com/a/40337942/654825 - there is a working jsFiddle also.
Upvotes: 3