Vorms: Vue form validation with Composition API
Tags: vue, javascript, webdev
Published: 2022-12-18 02:48:56

Forms are part of our lives on the web. We use them to take surveys, sign up for workshops, and apply for gym memberships. However, form validation and state management are difficult points in web front-end development.

While Vue's `v-model` directive helps us simplify form input binding, we still have a lot of details to deal with, such as: accessibility, validation, and printing out error messages for each field to ensure the correct value is submitted. .. etc.

So, I decided to build a library, which should be the simplest and most flexible, and just only focus on the core logic.

The final result: **Vorms - Vue Form Validation with Composition API**

![Vorms - Form Validation with Vue Composition API](https://raw.githubusercontent.com/Mini-ghost/vorms/main/docs/public/logo.svg)

## Introducing Vorms

Vorms is a form validation and state management library based on the Vue 3 Composition API. It has many features, as below:

### 💪 Type Strong

TypeScript is the trend of modern front-end development. Even for projects developed using JavaScript, choosing a library developed based on TypeScript can allow us to obtain richer intelligence perception during the development process and reduce the mental burden of use.

Vorms is written in TypeScript, with detailed TSDocs added to the core API. Users can easily understand how to use it and make the development experience better.

### 🛠 Composition API

[Composition API](https://vuejs.org/guide/extras/composition-api-faq.html) for better logic reuse. Vorms uses the Composition API, which allows us to easily extend the logic to face different scenarios.

Vorms has only four composition APIs:

- `useForm()`
A composition API that surrounds our entire form and manages the form state.

- `useField()`
A composition API that will return specific field value, meta (state) and attributes, you can also add validation for that field.

- `useFieldArray()`
A composition API that will return specific fields values, meta (state), attributes and provides common operation helpers, you can also add a validation for those fields.

- `useFormContext()`
A composition API that allow you access the form context. This is useful with deeply nested component structures.

This follow is the Vorms basic usage:

**setup script**

```ts
import { useForm } from '@vorms/core'

const starterOptions = ['Sprigatito', 'Fuecoco', 'Quaxly']

const { register, handleSubmit, handleReset } = useForm({
  initialValues: {
    pokemon: '',
  },
  // If `onSubmit()` function is synchronous, 
  // you need to call setSubmitting(false) yourself.
  async onSubmit(data) {
    await fetch(...)
  }
})

const { value, attrs } = register('pokemon')
```

**template**

```html
<form @submit="handleSubmit" @reset="handleReset">
  <label for="pokemon">First partner Pokémon</label>
  <select id="pokemon" v-model="value" v-bind="attrs">
    <option v-for="item in starterOptions" :key="item" :value="item">
      {{ item }}
    </option>
  </select>

  <button type="reset">Reset</button>
  <button type="submit">Get Start</button>
</form>
```

Vorms' pure Composition API makes it adaptable to any UI library, in follow is vorms work with [Vuetify](https://github.com/vuetifyjs/vuetify) and [Element-Plus](https://github.com/element-plus/element-plus)

{% embed https://stackblitz.com/edit/vorms-vuetify?embed=1&file=src/App.vue&hideExplorer=1&hideNavigation=1&view=preview&ctl=1 %}

{% embed https://stackblitz.com/edit/vorms-with-element-plus?embed=1&file=src/App.vue&hideExplorer=1&hideNavigation=1&view=preview&ctl=1 %}

> Refer [documentations](https://vorms.mini-ghost.dev/) for more details.

### 💡 Validation

Regarding form validation, we are most concerned about two issues, one is **when to call validation**, and the other is **how to call validation**

#### When to call validation

In some cases we want to have different form validation times before and after the first form submission. For example, to validate a form only if it is submitted before the first submission, if any field is invalid, validation will be re-run when typing into that field

Vorms provides two props to control these behaviors, `validationMode` and `reValidationMode`.

```ts
import { useForm } from '@vorms/core'

const { register, handleSubmit, handleReset } = useForm({
  initialValues: {
    pokemon: '',
  },
  validationMode: 'submit', // default is `submit`
  reValidationMode: 'input', // default is `change`
  async onSubmit(data) {
    await fetch(...)
  }
})

const { value, attrs } = register('drink')
```

By applying these two props, we can better control the timing of form validation. We won't validate the form too early, and yell at the user too early, making the user feel annoyed.

#### How to call validation

At present, there are many schema validation libraries on the npm package, such as: [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod)...etc.

In Vorms, we don't provide any built-in validation rules. Our goal is to allow every developer to freely choose a schema validation library or write their own validation function according to their own habits.

To this end, we wrote some validation resolvers ([@vorms/resolvers](https://www.npmjs.com/package/@vorms/resolvers)) so that we can easily integrate third-party schema validation libraries. And if you write the form validation rules yourself, you don't have to worry about redundant code turns your project into a monster with excess body fat.

**Vorms Example - Validate With Yup**

{% embed https://stackblitz.com/edit/vorms-validate-with-yup?embed=1&file=src/App.vue&hideExplorer=1&hideNavigation=1&view=preview&ctl=1 %}

**Vorms Example - Validate With Zod**

{% embed https://stackblitz.com/edit/vorms-validate-with-zod?embed=1&file=src/App.vue&hideExplorer=1&hideNavigation=1&view=preview&ctl=1 %}

## Thanks

Vorms are heavily inspired by the following awesome projects.

- [Formik](https://github.com/jaredpalmer/formik)
- [React Hook Form](https://github.com/react-hook-form/react-hook-form)
- [VeeValidate](https://github.com/logaretm/vee-validate)

## Onwards and upwards

Vorms has been used in many projects, but it is also a very new library, it will definitely have a lot of improvements and enhancements, I will continue to improve it, and any great ideas are also welcome to contribute.

If you like what you see or you are interested and want to use Vorms in your own projects, please like us on [GitHub](https://github.com/Mini-ghost/vorms).

Thanks for reading, hope this library could helps you. 💚