@bharathvaj95

Enterprise Vue - Form Components

How we moved away from spaghetti code

 

Bharathvaj Ganesan

Front end engineer

Subscription management platform that helps untangle recurring revenue businesses from spaghetti billing.

120 +

20 +

9000 +

50 +

300 +

Currencies

Countries

Employees 

 

Customers

Payment Gateways

 

Why Vue

  • Approachable
  • Easy to onboard a new hire
  • Better documentation compared to other libraries

Fast learning curve

  • Easily integrates with our monolithic legacy app
  • Develop complex ui animations with ease
  • Faster delivery of features

Versatile

 

  • Decoupled HTML, CSS, and JS
  • Single File Components
  • Dependency tracking system
  • Community driven

Design Principles

  • Minimal manual optimization efforts needed
  • Less in size when compared to the rivals
  • Finally, it suites our need

Performance

Forms are hard at scale.

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

      A simple form validation library.  

vee-validate

      A template-based validation library.    

vue-form-generator

      A schema-based form generator component. 

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-form />

  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

<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-form />

  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 />

  • phone_no

<text-field />

<text-field-form/>

<text-field/>

Creates signup_form form along with validators in the store

Creates phone_no text field inside signup_form

Nothing fancy. Just renders the UI

On User Input

signup_form

Form Store

<text-field-form />

  • phone_no

<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/>

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

value: "650 234 4534 "

On Destroy

<form/>

<signup-form />

signup_form

Form Store

<text-field-form />

  • phone_no

<text-field-form/>

Deletes signup_form form from the store

Deletes phone_no text field from signup_form

<text-field />

Validations

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

Takeaways

Thanks!

Building form field components in an enterprise-scale product

By Bharathvaj Ganesan

Building form field components in an enterprise-scale product

In an enterprise-scale product, it is quite challenging to build and maintain reusable forms using component-based frameworks like Vue, React..etc. We’ll be discussing how form fields are handled effectively at a large scale in a product like Chargebee using Vue.

  • 485