@bharathvaj95

Enterprise Vue - Form Components

How we moved away from spaghetti code

 

Bharathvaj Ganesan

Front end engineer

Why Vue

  • Fast learning curve
  • Versatile
 
  • Smaller in Size
  • Performance

Transition to vue was not smooth

Forms are hard at scale.

  • Maintaining form component state
  • Staying organised
  • Validations
  • Testing
  • Complex form fields

Why

Forms @ Chargebee

Let's dive into building forms

<form @submit.prevent="submitForm">
  <input type="text" v-model="username">
  <input type="submit" value="Submit">
</form>
new Vue({
  el:'#app',
  data:{
    username:null
  },
  methods:{
    submitForm:function(e) {
     ...
    }
  }
})

Basic form

This Code Pen yields

Form with client side validations

This Code Pen yields

Form with server side validations

Community Plugins

  • vue-form
  • vee-validate
  • vue-form-generator

This bin yields

Form using vue-form

  1. Validations are duplicated at client & server side.
  2. Handling server error messages.
  3. Spaghetti code - Submission & validation logic are shared between parent form & children.
  4. Difficult to perform testing.
  5. Not scalable in a large application with complex business logic.

Some observation

Taming the form beast

Goals

  • Make it simple.
  • Make it maintainable.
  • Make it easier to test.
  • Make it DRY.
  • Make it flexible.

Time for demo

<field />

Component Structure

<form />

<field-wrapper />

  1. Takes care of rendering the UI.
  2. Emits field events to the parent.
  3. Works independently without form wrapper.
  4. Custom masking of entered values.

<form-field />

  1. Wrapper container component
  2. On creation, registers the field to store form object.
  3. Attaches listeners to <field /> , validates them and updates the store.
  4. On destroy, removes the field from store. 

<field-wrapper />

  1. On creation, registers the form to the store.
  2. Loads client side form validations.
  3. Takes care of form submission part.
  4. On destroy, removes the form object from store.

<form />

Working

On Mount

<Form/>

<signup-form />

signup_form

Form Store

<text-field-form />

  • user_name

<text-field />

<text-field-form/>

<text-field/>

Creates signup_form form along with validators in the store

Creates user_name text field inside signup_form

Nothing fancy. Just renders the UI

On User Input

signup_form

Form Store

<text-field-form />

  • user_name

<text-field />

<text-field-form/>

  • Updates the form store on input.
  • Validates the field value on blur.
  • Sets the validation state in the store

<text-field/>

  • Sanitises the value and emits to the parent.
  • Renders the form state from the wrapper parent.

value: "Bruce Wayne"

On Destroy

<Form/>

<signup-form />

signup_form

Form Store

<text-field-form />

  • user_name

<text-field-form/>

Deletes signup_form form from the store

Deletes user_name text field from signup_form

<text-field />

  1. Separation of concerns.
  2. Harness power of Vue.
  3. API-First Development. (Open API Spec)
  4. Developer friendly.

Takeaways

Any Questions ?

Made with Slides.com