Dynamically binding the user's data

What good is any form if we can't use the data that the user inputs? As cool as it is that we can generate these forms dynamically based entirely on a schema, we still need to be able to store these values somehow so that we can later process them as we need. The first step for our form to be able to create two-way bindings is to tell Renderer.vue how to handle input events from the dynamic components.

Follow these steps:

  1. Let's go into Renderer.vue and add a :value binding, as well as an @input listener to the <component>:
      <component 
:is="component"
v-bind="props"
:value="value"
@input="handleComponentInput"
/>

Remember that, in order to v-model or two-way bind into a custom component, we usually need to pass in a value and listen to input events. In this case, we are going to explicitly listen to input events since our custom components all fire this type of event for two-way bindings. 

  1. Go ahead and add the new value prop to our Renderer component:
      props: {
element: {
type: Object,
required: true
},
value: {
required: true
}
}

Finally, we need to implement the handleComponentInput method. Keep in mind that I have chosen to make it a method instead of just firing the $emit directly into the template for two reasons. The first one is that I have found it to be a nice practice to more easily write unit tests later on, and second, it allows for more flexibility if we need to write an if statement or conditional for a particular component that has specific requirements.

  1. Add the new handleComponentInput method:
      methods: {
handleComponentInput (value) {
this.$emit('input', value);
}
}

Now that the renderer is ready to two-way bind with v-model, let's go back to App.vue, where we are implementing it and add the actual binding. We are going to add the v-model attribute to <Renderer>, and the trick here is that we are going to bind it to form[name]. Remember that our schema has a structure where the name of the property is the unique identifier for that field. Open schema.json to check it out.

For example, in the first field, firstName is the name of the property that holds the first space in the schema object. This property is what we are going to use to bind to so that we can, later on, know which field it represents in our data.

  1. Let's add our v-model to <Renderer> in App.vue:
      <Renderer 
v-for="(element, name) in schema"
:key="name"
:element="element"
v-model="form[name]"
/>

Open up your browser and check out your form; if you start filling out the fields and look at your Vue development tools, you will see that the bindings are all working correctly. What renderer is doing through the dynamic v-model is tying each one of the properties to a property on the form of local data.

  1. If you want a quicker way to see this in action without resorting to using the dev tools, add this following bit of code to your <Renderer> component in App.vue:
      <pre>{{ form }}</pre>

We are simply going to dump the form into the screen, and use the HTML <pre> tag to get some easy formatting. Try going into schema.json and adding some new fields. You will see the results on your browser immediately, as renderer will pick up on the changes of the schema and the page will reload by itself (hot reload). With the new schema in place, you will see all of your new fields in place.

We're getting places and fast! In the following section, we're going to prepare yet again for a demo API. In a real application, you are not going to be serving the schema from a fileā€”but probably from a server. Fire up Mockoon, and let's do this!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset