What's new in

vee-validate v4

Abdelrahman Awad

FE Engineer @

Creator ofย 

ee-validate

Hi ๐Ÿ‘‹

I'm

Why are you using vee-validate?

  • Most popular
  • Declarative
  • Built-in rules
  • Error Messages

Why are you NOT using vee-validate?

  • Large Bundle Size
  • Tons of template logic
  • Slow for large forms
  • Too verbose
  • Large learning curve
  • Inconsistent support for 3rd party component libraries

vee-validate v4 Goals

โœŒ Vue 3 Support

โœจ Better DX

โšก Faster Forms

Forms are Hard

  • UI states
  • Value tracking
  • Handling Submissions
  • Validation
  • A11y

Two Validation Flavors

  • Higher-order components
  • Composition API

ย 

Composition API

useField()

<template>
  <div>
    <input type="text" name="email" v-model="value">
    {{ errorMessage }}
  </div>
</template>

<script>
import { useField } from 'vee-validate';

export default {
  setup() {
    const { value, errorMessage } = useField(
      'email', 'required|email'
    );

    return {
      value,
      errorMessage
    };
  }
};
</script>

useForm()

import { useField, useForm } from 'vee-validate';

export default {
  setup() {
    const { form, handleSubmit } = useForm();
    const { value: password, errors: passwordErrors } = useField(
      'password', 'required', { form }
    );
    const { value: email, errors: emailErrors } = useField(
      'email', 'required', { form }
    );
    const onSubmit = handleSubmit(values => {
      // Send data to the API
      console.log(values);
    });

    return {
      password,
      passwordErrors,
      email,
      emailErrors,
      onSubmit
    };
  }
};

Higher-order Components

<Field />

  • Flexible Rendering with `as` prop
  • Scoped slots support for complex input markup
  • No `v-model` required
<Field name="firstName" as="input" />

<Field name="email" as="input" type="email" />

<Field name="drink" as="select">
  <option value="coffee">Coffee</option>
  <option value="tea">Tea</option>
  <option value="coke">Coke</option>
</Field>

<Field name="email" as="custom-text-input" />

<Field />

<Field v-slot="{ field }">
  <!-- This will be validated -->
  <input v-bind="field">
  
  <!-- This won't be validated -->
  <input class="addon" type="checkbox">
</Field>

You can use `v-slot` to render more complex markup

<Form />

  • Flexible Rendering with `as` prop
  • Automatic validation before `submit`
  • scoped slots support for complex form markup
<Form as="form" @submit="onSubmit">
  <Field name="email" as="input" type="email" />
  
  <button type="submit">
    Submit
  </button>
</Form>

<ErrorMessage />

  • Shows form errors
  • a11y support
  • Scoped slot support for complex markup
<Form as="form" @submit="onSubmit">

  <Field name="email" as="input" type="email" />
  <ErrorMessage name="email" />

  <button>Submit</button>
</Form>

Validation

  • Simpler Validation Rules
  • Support for `yup` validation
  • Field-level and Form-level validation

Built in support for `yup`

import * as yup from 'yup';
  
export default {
  components: {
    // ...
  },
  setup() {
    const emailSchema = yup.string()
                           .required()
                           .email();
    
    return {
      emailSchema,
      // ...
    };
  }
};

Built in support for `yup`

<Form as="form" @submit="onSubmit">
  <Field 
    name="email"
    as="input"
    type="email" 
    :rules="emailSchema"
  />
  <ErrorMessage name="email" />

  <button>Submit</button>
</Form>

Old syntax still supported

<Form as="form" @submit="onSubmit">
  <Field 
    name="email"
    as="input"
    type="email" 
    rules="required|email"
  />
  <ErrorMessage name="email" />

  <button>Submit</button>
</Form>

Form-level validation schema

export default {
  setup() {
    // ...
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });
    
    return {
      schema,
      // ...
    }
  }
};

Form-level validation schema

<Form 
  :validation-schema="schema"
  as="form"
  @submit="submit"
>
  <Field name="email" as="input" />
  <ErrorMessage name="email" />

  <Field name="name" as="input" />
  <ErrorMessage name="name" />

  <Field name="name" as="input" type="password" />
  <ErrorMessage name="password" />

  <button>Submit</button>
</Form>

Other highlights

  • Entire core library size is 3.5kb minified and gzipped
  • No more rules caveats
  • No VNode event injections or tree traversals
  • Built-in rules are moved to @vee-validate/rules
  • Localization Module moved to @vee-validate/i18n

Demo ๐Ÿคž

It's out ๐ŸŽ‰

You can try out vee-validate v4 with Vue 3 now

yarn add vee-validate@next

# or

npm install vee-validate@next

๐Ÿ“š Documentation

(Still WIP)

Thanks ๐Ÿ‘‹

Made with Slides.com