Validate Forms In Vue Apps With Yup – vue-yup-form

Install & Download:

MIT

Description:

vue-yup-form is a Vue 3/2 component to provide headless form validation with the Yup library,  a schema builder for runtime value parsing and validation.

How to use it:

1. Import both vue-yup-form and Yup packages.

import { computed, ref, shallowRef } from "vue";
import { defineForm, field, isValidForm, toObject } from "vue-yup-form";
import * as yup from "yup";

2. Generate a simple form with vue-yup-form integrated.

<template>
  <div id="root">
    <form @submit.prevent="onSubmit">
      <div>
        <label>First Name *</label>
        <input
          name="firstName"
          type="text"
          placeholder="First Name"
          v-model.trim="form.firstName.$value"
        />
        <span v-if="submitted && form.firstName.$error">{{
          form.firstName.$error.message
        }}</span>
      </div>
      <div>
        <label>Last Name *</label>
        <input
          name="lastName"
          type="text"
          placeholder="Last Name"
          v-model.trim="form.lastName.$value"
        />
        <span v-if="submitted && form.lastName.$error">{{
          form.lastName.$error.message
        }}</span>
      </div>
      <div>
        <label>Employed</label>
        <input name="employed" type="checkbox" v-model="form.employed.$value" />
      </div>
      <div>
        <label>Favorite Color</label>
        <select name="favoriteColor" v-model="form.favoriteColor.$value">
          <option :value="null"></option>
          <option value="#ff0000">❤️ Red</option>
          <option value="#00ff00">💚 Green</option>
          <option value="#0000ff">💙 Blue</option>
        </select>
      </div>
      <div>
        <label>Toppings</label>
        <select multiple name="toppings" v-model="form.toppings.$value">
          <option value="chicken">🐓 Chicken</option>
          <option value="ham">🐷 Ham</option>
          <option value="mushrooms">🍄 Mushrooms</option>
          <option value="cheese">🧀 Cheese</option>
          <option value="tuna">🐟 Tuna</option>
          <option value="pineapple">🍍 Pineapple</option>
        </select>
      </div>
      <div>
        <label>Sauces</label>
        <div>
          <label>
            <input
              name="sauces"
              type="checkbox"
              value="ketchup"
              v-model="form.sauces.$value"
            />
            Ketchup
          </label>
          <label>
            <input
              name="sauces"
              type="checkbox"
              value="mustard"
              v-model="form.sauces.$value"
            />
            Mustard
          </label>
          <label>
            <input
              name="sauces"
              type="checkbox"
              value="mayonnaise"
              v-model="form.sauces.$value"
            />
            Mayonnaise
          </label>
          <label>
            <input
              name="sauces"
              type="checkbox"
              value="guacamole"
              v-model="form.sauces.$value"
            />
            Guacamole 🥑
          </label>
        </div>
      </div>
      <div>
        <label>Best Stooge</label>
        <div>
          <label>
            <input
              name="stooge"
              type="radio"
              value="larry"
              v-model="form.stooge.$value"
            />
            Larry
          </label>
          <label>
            <input
              name="stooge"
              type="radio"
              value="moe"
              v-model="form.stooge.$value"
            />
            Moe
          </label>
          <label>
            <input
              name="stooge"
              type="radio"
              value="curly"
              v-model="form.stooge.$value"
            />
            Curly
          </label>
        </div>
      </div>
      <div>
        <label>Notes</label>
        <textarea
          name="notes"
          placeholder="Notes"
          v-model.trim="form.notes.$value"
        />
      </div>
      <div class="buttons">
        <button type="submit" :disabled="submitting">Submit</button>
        <button type="button" @click="onReset" :disabled="submitting">
          Reset
        </button>
      </div>
      <pre>{{ values }}</pre>
    </form>
  </div>
</template>
<script setup lang="ts">
  const generateForm = () => {
    return defineForm({
      firstName: field("", yup.string().required()),
      lastName: field("", yup.string().required()),
      employed: field(false),
      favoriteColor: field<string | null>(null),
      toppings: field<string[]>([]),
      sauces: field<string[]>([]),
      stooge: field<string>("larry"),
      notes: field(""),
    });
  };
  const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
  // To use reset button, wrap with shallowRef()
  const form = shallowRef(generateForm());
  const submitted = ref(false);
  const submitting = ref(false);
  const onSubmit = async () => {
    submitted.value = true;
    submitting.value = true;
    try {
      if (!isValidForm(form.value)) {
        alert("Please check your entries.");
        window.scrollTo(0, 0);
        return;
      }
      await sleep(300);
      alert(JSON.stringify(toObject(form.value), null, 2));
    } finally {
      submitting.value = false;
    }
  };
  const onReset = () => {
    form.value = generateForm();
  };
  const values = computed(() => toObject(form.value));
</script>

Preview:

vue-yup-form

Add Comment