Tutorial

PSA: Proper Form Handling in Vue.js

Published on November 6, 2017
author

Joshua Bemenderfer

PSA: Proper Form Handling in Vue.js

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!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Joshua Bemenderfer

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I’ve been using this approach for a while now and feel like it’s the most programmatic approach and makes the most sense. I’m wondering though if instead of using the v-model, you can just pass along the values from the submit event to an Axios post request.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.