Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Validation Messages and Composition API

Form validation is an important part of any app.

In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.

Validation Messages Placeholder Interpolation

We can add placeholders into our validation messages and interpolate them when displaying the messages.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="name" rules="between:0,10" />
    <span>{{ errors.name }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import { between } from "@vee-validate/rules";
import { localize } from "@vee-validate/i18n";

defineRule("between", between);

configure({
  generateMessage: localize("en", {
    messages: {
      between: "The {field} value must be between 0:{min} and 1:{max}",
    },
  }),
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

{field} , 0:{min} , and 1:{max} are the placeholders in our validation message string.

0:{min} and 1:{max} are the rule arguments.

{field} is the rule name.

Composition API

Vee-Validate 4 comes with hooks for the Composition API.

For example, we can write:

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

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

export default {
  setup() {
    function validate(value) {
      if (!value) {
        return "This field is required";
      }

      if (value.length < 3) {
        return "Must contain more than 3 characters";
      }

      return true;
    }

    const { value, errorMessage } = useField("fieldName", validate);

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

We call the useField function with the field name as the first argument.

And the 2nd argument is the function we use for validation.

Returning true means that the inputted value, which is the value parameter, is valid.

We return the form validation error message if it’s not valid.

useField returns the errorMessage that we display in the template.

We can also use the yup library for validation.

For instance, we can write:

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

<script>
import { useField } from "vee-validate";
import * as yup from "yup";

export default {
  setup() {
    const { value, errorMessage } = useField(
      "fieldName",
      yup.string().required().min(3)
    );

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

to make sure that the entered value has at least 3 characters.

We can also use global validators.

For example, we can write:

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

<script>
import { defineRule, useField } from "vee-validate";
import * as rules from "@vee-validate/rules";
Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  setup() {
    const { value, errorMessage } = useField("fieldName", "required|min:3");

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

to add the rule with the built-in validators.

We have to call defineRule to add the rules first.

Conclusion

We can customize validation messages with Vee-Validate 4.

Also, we can use the hooks with the Composition API to add validation to our Vue 3 app.

Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Validation Messages

Form validation is an important part of any app.

In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.

Localized Messages

We can add validation messages for different locales with the @vee-validate/i18n package.

To install it, we run:

yarn add @vee-validate/i18n

or:

npm install @vee-validate/i18n

to install the package.

Then we can use it by writing:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="name" rules="required" />
    <span>{{ errors.name }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import { required } from "@vee-validate/rules";
import { localize } from "@vee-validate/i18n";

defineRule("required", required);

configure({
  generateMessage: localize("en", {
    messages: {
      required: "This field is required",
    },
  }),
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We call defineRule to add the required rule.

Then we call configure with an object with the generateMessage property.

We call localize with the locale string and the messages to add the English language message for the required rule.

Also, we can add messages for multiple locales using the localize function:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="name" rules="required" />
    <span>{{ errors.name }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import { required } from "@vee-validate/rules";
import { localize, setLocale } from "@vee-validate/i18n";

defineRule("required", required);

configure({
  generateMessage: localize({
    en: {
      messages: {
        required: "This field is required",
      },
    },
    fr: {
      messages: {
        required: "Ce champ est requis",
      },
    },
  }),
});

setLocale("fr");

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We add an object with the locale names as the keys and the messages inside it.

Then we call setLocale to set the locale.

We have the required property with the message for each property to set the message for the required rule.

Now the French validation error messages will be shown.

Also, we can add built-in messages for the rules.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="name" rules="required" />
    <span>{{ errors.name }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import { required } from "@vee-validate/rules";
import { localize, setLocale } from "@vee-validate/i18n";
import en from "@vee-validate/i18n/dist/locale/en.json";
import fr from "@vee-validate/i18n/dist/locale/fr.json";

defineRule("required", required);

configure({
  generateMessage: localize({
    en,
    fr,
  }),
});

setLocale("fr");

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to import the validation messages provided by Vee-Validate 4.

Then we pass them into the object we pass into the localize function.

Conclusion

We can add custom validation messages with Vee-Validate 4 in our Vue 3 app.

Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Required Fields and Validation Messages

Form validation is an important part of any app.

In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.

required

The required rule lets us validate that a value is entered into the input.

For example, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="required" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

Also, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { required: true },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the rule with an object.

size

The size rule lets us validate the file doesn’t exceed the given size in kilobytes.

For example, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" type="file" rules="size:100" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to validate that the selected file is less than 100 kilobytes.

Also, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" type="file" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the same rule.

Global Message Generator

We can change how the validation messages are generated.

To do this, we write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="email" rules="required|email" />
    <span>{{ errors.email }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

configure({
  generateMessage: (context) => {
    return `The field ${context.field} is invalid`;
  },
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We call the configure method with the generateMessage method to return the validation error message.

context has the field data. context.field has the field name.

So when we type in something other than an email address, we get The field email is invalid displayed.

We can set the label prop to set the value of context.field to the value of the label prop:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="email" label="Email" rules="required|email" />
    <span>{{ errors.email }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule, configure } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

configure({
  generateMessage: (context) => {
    return `The field ${context.field} is invalid`;
  },
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { size: 100 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

Now we see The field Email is invalid when we type in something other than an email address.

Conclusion

We can validate required fields and selected file sizes with Vee-Validate 4 in our Vue 3 app.

Also, we configure Vee-Validate 4 to show the validation messages we want.

Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Number Validation

Form validation is an important part of any app.

In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.

min

The min rule specifies that the length of the inputted value shouldn’t be less than the specified length.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="min:3" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We set the min value to 3 to set the minimum length that we allow for the inputted value.

Also, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { min: 3 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the same rule.

min_value

The min_value rule lets specify the min value that we allow as the inputted value.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="min_value:5" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

If we enter a number less than 5, we’ll see an error.

Also, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { min_value: 5 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the same rule.

numeric

The numeric rule lets us validate that the inputted value is a number.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="numeric" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the rule.

Also, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>

<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { numeric: true },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the same rule.

Conclusion

We can validate numeric inputs in our Vue 3 app with Vee-Validate 4.

Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Max Values and MIME Types

Form validation is an important part of any app.

In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.

max

We can use the max rule to make sure the entered value doesn’t exceed the specified length.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="max:10" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We add the max length after the colon.

So if we entered something that’s more than 10 characters long, an error will be displayed.

Also, we can pass an object into the rules prop to add the same rule:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "[@vee](https://medium.com/r/?url=http%3A%2F%2Ftwitter.com%2Fvee "Twitter profile for @vee")-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { max: 10 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

max_value

The max_value prop lets us make sure that the inputted value doesn’t exceed the given number.

For example, we can use it by writing:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" rules="max_value:10" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We add the max number to check for after the colon.

If we enter a number bigger than 10, we’ll see an error displayed.

Also, we can use an object to add the rule:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { max_value: 10 },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

mimes

We can use the mimes rule to check that the selected file has the given MIME type.

For instance, we can write:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" type="file" rules="mimes:image/jpeg" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

to add the rule to a file input.

We can also add the rule with an object:

<template>
  <Form @submit="onSubmit" v-slot="{ errors }">
    <Field name="field" type="file" :rules="validations" />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Form, Field, defineRule } from "vee-validate";
import * as rules from "@vee-validate/rules";

Object.keys(rules).forEach((rule) => {
  defineRule(rule, rules[rule]);
});

export default {
  components: {
    Form,
    Field,
  },
  data() {
    return {
      validations: { mimes: ["image/jpeg"] },
    };
  },
  methods: {
    onSubmit(values) {
      alert(JSON.stringify(values, null, 2));
    },
  },
};
</script>

We put the MIME type we allow in the mimes array property.

Conclusion

We can validate MIME types of files, max length of input, and max value of an input within our Vue 3 app with Vee-Validate 4.