@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
- Validations are duplicated at client & server side
- Handling server error messages
- Spaghetti code - Submission & validation logic are shared between parent form & children
- Difficult to perform testing
- 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 />
- Takes care of rendering the UI
- Emits field events to the parent
- Works independently without form wrapper
- Custom masking of entered values
<field />
- Wrapper container component
- On creation, registers the field to store form object
- Attaches listeners to <field /> , validates them and updates the store
- On destroy, removes the field from store
<field-form />
- On creation, registers the form to the store
- Loads client side form validations
- Takes care of form submission part
- 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
- Separation of concerns
- Harness power of Vue
- API-First Development. (Open API Spec)
- 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.
- 875