Monday, 6 November, 2017 UTC


Summary

Forms are an integral part of almost any web application. They’re really just ways of getting information from the user and turning it into some sort of machine-readable data model. Thing is, not everyone realizes exactly how the HTML form element works, and how it can simplify their lives, especially when it comes to handling user submission and event binding in libraries like Vue.js. Now’s the time to set the record straight.
The Bad Way
More often then not, I see people doing things like this: (Binding their data submission handlers to the parent element and button click event.)
<template> <div @keydown.enter="handleSubmit"> <label> Email: <input type="email" v-model="user.email"/> </label> <label> Name: <input type="text" v-model="user.name"/> </label> <label> Password: <input type="password" v-model="user.password"/> </label> <button @click="handleSubmit">Submit</button> </div> </template> <script> export default { data() { return { user: { email: '', name: '', password: '' } } }, methods: { handleSubmit() { // Send data to the server or update your stores and such. } } } </script> 
Now, there are dozens of reasons that this is a bad idea. For one thing, it makes it difficult for screen readers and the likes to know that they’re in a form. Additionally, you have to bind the event handler to both the button and the containing element, and it still doesn’t really handle every use-case. You should pretty much never be doing anything like this.
The Good Way
So what should you be doing? Well, actually it’s really simple. Use the <form> element!
<template> <!-- @submit handles any form of submission. --> <!-- .prevent keeps the event from bubbling around and doing anything else. --> <form @submit.prevent="handleSubmit"> <label> Email: <input type="email" v-model="user.email"/> </label> <label> Name: <input type="text" v-model="user.name"/> </label> <label> Password: <input type="password" v-model="user.password"/> </label> <button type="submit">Submit</button> </form> </template> <script> export default { data() { return { user: { email: '', name: '', password: '' } } }, methods: { handleSubmit() { // Send data to the server or update your stores and such. } } } </script> 
Boom. Clicking the button is handled. Pressing enter is handled. Any other method of form submission, past, present, or future, is handled.
It seems quite a few front-end developers forget about or ignore the good ‘ol <form> element. Possibly because of misconceptions / horrible memories from their traditional hosted PHP-rendered-page days. Often, the misconceptions that prevent developers from using the <form> element include these:
  • Assuming it forces a page refresh.
  • Assuming you have to set the method and action properties that make an uncontrollable request.
  • Assuming you have to set a unique name for your form.
None of those are true. With nothing else set, a form is really just a convenient wrapper for input fields that allows you to handle any form of submission the user chooses without any extra logic.
So go on and use <form>. I don’t want to see anyone else handling keypresses and button clicks manually for user input. Just use the element HTML gave you!