Show of hands: When you’re building a web application, what’s your favorite part of the process? Did you say “implementing the forms”? No one ever does.
Forms are essential yet painful. User experience expectations are high, but since we’re always starting with primitive HTML elements (even when using React or Vue), it requires a lot of effort to build high-quality forms. The developer experience is marred with inconsistent input tags, poor frontend validation, accessibility requirements, and lots of tedious markup, just to name a few frustrations.
What if we standardized the API for all inputs so that each input type was predictable and even interchangeable? What if we had access to an expressive syntax for executing complex frontend validation? What if we super-charged v-model
so that it could be applied once to an entire form
element to generate a single object from our form data?
What if we learned from Vue — built an easy-to-understand API that didn’t restrict power users — and focused our energy on reinventing the form-authoring experience? Developers would be a heck of a lot happier, and we’d all save a ton of time. These quality-of-life improvements, and many others, are available with Vue Formulate. Let’s take a look.
Let’s start with a simple example doing things the traditional Vue way we’re familiar with. Below is a mock user sign-up form for a (fake) conference. In this example, we’re asking for a username, email, short bio, password, and password confirmation.
See the Pen
1 – Intro to Vue Formulate – Vanilla Registration Form by Andrew Boyd (@boyd)
on CodePen.
This is a simple form, but already there’s a number of headaches we’ve had to deal with when authoring it:
textarea
is its own discrete tag differing from everything elseLet’s add in the password confirmation validation and stub out the username availability check from the above list. After all, our users are going to expect nice UX behaviors, and we’re not going to ship this form without them — right?
Once again, we’ll use the same vanilla Vue approach we’re already familiar with. After a bit more work, we end up with something that looks like this:
See the Pen
2 – Intro to Vue Formulate – Vanilla Registration Form w/ Custom Validation by Andrew Boyd (@boyd)
on CodePen.
The user experience on the form is nicer, but our simple example is starting to look… complicated. Note the addition of several ref
attributes to help us track input values in our component as well as keyup
and blur
event handlers for triggering our own custom validation methods. These work well enough, but in the case of the username check, it’s possible to quickly submit the form with an invalid username due to the async nature of the availability check.
Our component now contains all of this complexity — in an admittedly imperfect state — and this is for a form with only five inputs! On top of that, all the logic we’ve written in our component is bound to this particular form and is not easily reusable. Reuse will require us to do additional work to abstract our validation functionality away into a utility library somewhere in our project or, worse, just copy/paste and modify it whenever we author another form that requires similar behaviors.
We should do better. We can do better. Let’s take look at the same form written with Vue Formulate.
See the Pen
3 – Intro to Vue Formulate – Registration Form Rewrite with Vue Formulate by Andrew Boyd (@boyd)
on CodePen.
Ah! Much nicer. All of the same functionality we had hand-rolled (and more), the template is cleaner (our component’s template code was cut in half), and our component contains less one-off logic. There are some key items to address in the above demo:
FormulateForm
and FormulateInput
. That’s it!^
prefix on validation rules, we can tell Vue Formulate to “bail” on validation if that particular rule fails, limiting the number of errors shown at one timeNot only is the code concise and easier to understand at a glance, Vue Formulate is providing us with some great UX features for free. Validation rules produce well-formatted error messages, the form itself will not submit until all validation rules (including async rules) have passed, and labels and help text exist as props on FormulateInput
, allowing for the same improved UX our users expect without requiring bloated markup to be written in our template.
All of this and we’re only scratching the surface of Vue Formulate’s features.
We’re going to build a multi-attendee purchase form for a (fake) conference (FormulateConf 2020) and use it as an opportunity to showcase some of Vue Formulate’s more powerful features.
To start, we’ll scaffold out our form’s functionality for a single attendee, with inputs to capture a name, email, ticket tier, and preferred payment method. We’ll add Vue Formulate validation, labels, and help text since we’re now familiar with them.
See the Pen
4 – Intro to Vue Formulate – Single-Member Booking Form by Andrew Boyd (@boyd)
on CodePen.
This is great! We would be ready to roll if we only needed our form to account for a single user at a time. Instead, we want to allow a user (for example, an office manager) to book tickets for multiple attendees and submit the form as a single payment. This is a perfect use case for Vue Formulate’s repeatable grouped fields.
Let’s do a minimal amount of refactoring to take advantage of repeatable groups.
See the Pen
5 – Intro to Vue Formulate – Multi-Member Booking Form by Andrew Boyd (@boyd)
on CodePen.
Huzzah! By wrapping our user detail fields in a FormulateInput
of type group
and setting the repeatable
prop to true
, we’re able to implement repeatable fields out of the box. That was too easy! We’ve also added a v-model
attribute to the group and revised our total
computed property to sum up the one-or-many tickets represented in our form data. Pretty neat, huh?
In Vue Formulate, v-model
is powerful and works exactly how you hope it would. You can model more than just single inputs or grouped fields. Let’s slap a v-model
on the root FormulateForm
element itself. We’ll output its value onto the page so that we can see the data structure provided by Vue Formulate as we interact with the form.
See the Pen
6 – Intro to Vue Formulate – Multi-Member Booking Form with v-model output by Andrew Boyd (@boyd)
on CodePen.
And that’s that! While the functionality we’ve created is complex, what we are left with is a component that is refreshingly easy to read and requires minimal custom logic to power its experience.
Vue Formulate dramatically reduces the complexity involved in writing forms with Vue. We’ve covered a lot of ground in this introduction, but there’s plenty more to explore. With Vue Formulate you can also:
FormulateInput
elementVue Formulate is — and always will be — free and open source. Our comprehensive developer documentation will help you integrate Vue Formulate into your next project. Bonus: because it’s <15KB gzipped, you don’t even need to feel guilty about it. Add Vue Formulate to your project and go build something awesome!
Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps, including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.
The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error and what state the application was in when an issue occurred.
Modernize how you debug your Vue apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.