Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Initial Values and Setting Form Values

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.

Initial Values

We can set the initial values of the form with the initial-values prop.

To do this, we write:

<template>
  <Form :validation-schema="schema" :initial-values="formValues">
    <Field name="email" as="input" />
    <Field name="name" as="input" type="text" />
    <Field name="password" as="input" type="password" />

<button type="Submit">Submit</button>
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    const formValues = {
      email: "example@example.com",
      name: "Jane Smith",
      password: "password",
    };

    return {
      schema,
      formValues,
    };
  },
};
</script>

We set the initial-values prop with the object with the values.

Setting Form Values

We can set form values using the setFieldValue or setValues methods.

For example, we can write:

<template>
  <Form v-slot="{ setFieldValue, setValues }">
    <Field name="email" as="input" />
    <ErrorMessage name="email" />

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

    <button type="button" @click="setFieldValue('email', 'test')">
      Set Values
    </button>
    <button
      type="button"
      @click="setValues({ email: 'test', password: 'test12' })"
    >
      Set Multiple Values
    </button>
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    const formValues = {
      email: "example@example.com",
      name: "Jane Smith",
      password: "password",
    };

    return {
      schema,
      formValues,
    };
  },
};
</script>

We have one button that calls setFieldValue to set a single form value.

The first argument is the form field name and the 2nd argument is the value.

The setValues method lets us pass in an object with the form field names as the keys and their corresponding value.

Also, we can use these methods in the submit callback.

For example, we can write:

<template>
  <Form @submit="onSubmit">
    <Field name="email" as="input" />
    <ErrorMessage name="email" />

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

    <input type="submit" />
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    const formValues = {
      email: "example@example.com",
      name: "Jane Smith",
      password: "password",
    };

    return {
      schema,
      formValues,
    };
  },
  methods: {
    onSubmit(values, actions) {
      actions.setFieldValue("email", "abc@example.com");
      actions.setValues({
        email: "abc@example.com",
        password: "password1",
      });
    },
  },
};
</script>

We call setFieldValue in the onSubmit submit handler to set a single form value.

And we call actions.setValues to set multiple values.

values has the original values before calling these methods.

Form validation will be triggered when calling these methods.

We can also call these methods from the ref of the form:

<template>
  <Form @submit="onSubmit" ref="myForm">
    <Field name="email" as="input" />
    <ErrorMessage name="email" />

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

    <input type="submit" />
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    const formValues = {
      email: "example@example.com",
      name: "Jane Smith",
      password: "password",
    };

    return {
      schema,
      formValues,
    };
  },
  methods: {
    onSubmit(values, actions) {
      this.$refs.myForm.setFieldValue("email", "abc@example.com");
      this.$refs.myForm.setValues({
        email: "abc@example.com",
        password: "password1",
      });
    },
  },
};
</script>

Conclusion

We can set the initial values of the form with the initial-values prop.

And we can change the form values with dedicated methods with Vee-Validate 4.

Categories
Vue 3

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

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.

Handling Submissions

We can submit form data directly to a given URL.

For example, we can write:

<template>
  <Form
    method="post"
    action="https://reqres.in/api/users"
    :validation-schema="schema"
  >
    <Field name="email" as="input" />
    <Field name="name" as="input" type="email" />
    <Field name="password" as="input" type="password" />
    <input type="submit" />
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
};
</script>

We set the method to 'post' and action to the URL that we want to submit our form data to do to the submission.

It’ll only run when the inputted values are valid.

Also, we can manually handle our submissions to handle it the way we like.

For example, we can write:

<template>
  <VeeForm v-slot="{ handleSubmit }" :validation-schema="schema" as="div">
    <form @submit="handleSubmit($event, onSubmit)">
      <Field name="email" as="input" type="text" />
      <Field name="name" as="input" type="text" />
      <Field name="password" as="input" type="password" />

      <button>Submit</button>
    </form>
  </VeeForm>
</template>

<script>
import { Form as VeeForm, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    VeeForm,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
  methods: {
    onSubmit(values) {
      console.log(values);
    },
  },
};
</script>

We add the Form component and get the handleSubmit method from the slot prop.s

Then we can use the as the submit event handler with the submit $event object and our own onSubmit method to do the submissioins.

Then when we the fields are all valid and we click Submit, we see the data in values logged.

Also, we can use the submitForm method from the slot props to submit directly to a URL.

To do this, we write:

<template>
  <VeeForm v-slot="{ submitForm }" :validation-schema="schema" as="div">
    <form
      @submit="submitForm"
      method="post"
      action="https://reqres.in/api/users"
    >
      <Field name="email" as="input" type="text" />
      <Field name="name" as="input" type="text" />
      <Field name="password" as="input" type="password" />

      <button>Submit</button>
    </form>
  </VeeForm>
</template>

<script>
import { Form as VeeForm, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    VeeForm,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
};
</script>

We set the submit event handler to the submitForm method.

And we set the method and action so we can submit our form data to that URL.

Also, we can use the validate method to validate our form inputs:

<template>
  <Form v-slot="{ validate }" :validation-schema="schema">
    <Field name="email" as="input" />
    <Field name="name" as="input" type="text" />
    <Field name="password" as="input" type="password" />
    <button type="button" @click="validate">Submit</button>
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
};
</script>

We also get the validate method from the slot props.

Conclusion

We can use the functions from the slot props of the Form component to validate submissions and submit data.

Categories
Vue 3

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

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.

ErrorMessage Component

We can use the ErrorMessage component to display error messages.

For example, we can write:

<template>
  <Form>
    <Field name="field" as="input" :rules="rules" />
    <ErrorMessage name="field" />
  </Form>
</template>

<script>
import { Field, Form, ErrorMessage } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Field,
    Form,
    ErrorMessage,
  },
  data() {
    const rules = yup.string().required();

    return {
      rules,
    };
  },
};
</script>

We add the ErrorMessage component and set the name prop to the value of the name prop of the Field component to display the validation error messages for the field.

Custom Labels with Yup

We can change the label of the field.

For example, we can write:

<template>
  <Form :validation-schema="schema">
    <Field name="emailAddr" as="input" />
    <ErrorMessage name="emailAddr" />

    <Field name="accPassword" as="input" />
    <ErrorMessage name="accPassword" />
  </Form>
</template>

<script>
import { Field, Form, ErrorMessage } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Field,
    Form,
    ErrorMessage,
  },
  data() {
    const schema = yup.object().shape({
      emailAddr: yup.string().email().required().label("Email Address"),
      accPassword: yup.string().min(5).required().label("Your Password"),
    });
    return {
      schema,
    };
  },
};
</script>

We call the label method to change the field label.

And when we see the validation error message, we’ll see the field labels display in the error messages.

Form Values

We can get the form values from the slot props of the Form component.

For example, we can write:

<template>
  <Form v-slot="{ values }" :validation-schema="schema">
    <Field name="email" as="input" />
    <Field name="name" as="input" type="email" />
    <Field name="password" as="input" type="password" />

    <pre>
      {{ values }}
    </pre>
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
};
</script>

The values property from the slot props has the form values.

So when we type into them, we’ll see the values displayed.

To access the form values in the component object, we can access them from the parameter of the submit handler:

<template>
  <Form @submit="onSubmit" :validation-schema="schema">
    <Field name="email" as="input" />
    <Field name="name" as="input" type="email" />
    <Field name="password" as="input" type="password" />
    <input type="submit" />
  </Form>
</template>

<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      name: yup.string().required(),
      password: yup.string().required().min(8),
    });

    return {
      schema,
    };
  },
  methods: {
    onSubmit(values) {
      console.log(values);
    },
  },
};
</script>

We add the submit event handler.

Then in the submit event handler, we can access the form values from the values parameter.

When we click submit and the inputted values are all valid, then the onSubmit method will be run.

Conclusion

We can display error messages with the ErrorMessage component.

Also, we can display form values from the slot props and get the form values in the submit handler.

Categories
Vue 3

Form Validation in a Vue 3 App with Vee-Validate 4 — Validation Behavior and Error 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.

Validation Behavior

Vee-Validate runs validate when the change event is emitted or when the value is changed externally.

Customizing Validation Triggers

We can change when fields are validated.

To do this, we use the configure function to change this behavior:

<template>
  <Form @submit="submit" :validation-schema="schema" v-slot="{ errors }">
    <Field name="email" as="input" />
    <span>{{ errors.email }}</span>
    <br />
    <Field name="password" as="input" type="password" />
    <span>{{ errors.password }}</span>
    <br />
    <button>Submit</button>
  </Form>
</template>
<script>
import { configure, Field, Form } from "vee-validate";  `
import * as yup from "yup";
configure({
  validateOnBlur: true,
  validateOnChange: true,
  validateOnInput: false,
  validateOnModelUpdate: true,
});
export default {
  components: {
    Field,
    Form,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      password: yup.string().required().min(8),
    });
    return {
      schema,
    };
  },
  methods: {
    submit() {},
  },
};
</script>

validateOnBlur means validation will run when the blur event is emitted.

validateOnChange means validation will run when the change event is emitted.

validateOnInput means validation runs when the input event is emitted.

And validateInModelUpdate means validation runs when the model reactive properties updates.

Displaying Error Messages

We can create our own field and display the error messages by using the slot props.

For instance, we can write:

<template>
  <Form @submit="submit" :validation-schema="schema">
    <Field :rules="rules" v-slot="{ field, errors, errorMessage }" name="email">
      <input v-bind="field" type="text" />
      <p>{{ errors[0] }}</p>
      <p>{{ errorMessage }}</p>
    </Field>
    <br />
    <button>Submit</button>
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Form,
    Field,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
    });

    return {
      schema,
    };
  },
  methods: {
    submit() {},
  },
};
</script>

We have the validation-schema prop with the validation schema.

And in the Field component, we have the input element.

We pass in the field properties as props to make the validation trigger on the input.

And we show the errors with the errors[0] or errorMessage expressions.

Also, we can display all the error messages for the fields by iterating over the errors object:

<template>
  <Form v-slot="{ errors }" :validation-schema="schema">
    <template v-if="Object.keys(errors).length">
      <p>Please correct the following errors</p>
      <ul>
        <li v-for="(message, field) in errors" :key="field">
          {{ message }}
        </li>
      </ul>
    </template>

    <Field name="name" as="input" :rules="rules" />
    <Field name="email" as="input" :rules="rules" />
    <Field name="password" as="input" :rules="rules" />
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Field,
    Form,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      password: yup.string().required().min(8),
      name: yup.string().required(),
    });
    return {
      schema,
    };
  },
  methods: {
    submit() {},
  },
};
</script>

We get the keys from the errors object and loop through them with the v-for directive.

The message is the value, and we display them in the li .

Conclusion

We can change when validation is run and display error messages our way in our Vue 3 app with Vee-Validate 4.

Categories
Vue 3

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

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.

Field Level Validation

We can validate fields with the Field component.

For instance, we can write:

<template>
  <Form v-slot="{ errors }">
    <Field name="field" as="input" :rules="isRequired" />
    <br />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
export default {
  components: {
    Field,
    Form,
  },
  methods: {
    isRequired(value) {
      return value ? true : "This field is required";
    },
  },
};
</script>

We have the Field component which has the as prop to set the tag name of the element to render.

rules has the field validation function.

The isRequired function returns true if the value is valid and a validation error message otherwise.

value has what we inputted.

We can also use 3rd party libraries for validation.

For example, we can use the yup library for validation by writing:

<template>
  <Form v-slot="{ errors }">
    <Field name="field" as="input" :rules="passwordRules" />
    <br />
    <span>{{ errors.field }}</span>
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";

export default {
  components: {
    Field,
    Form,
  },
  data() {
    return {
      passwordRules: yup.string().required().min(8),
    };
  },
};
</script>

We have the passwordRules reactive property which is set to yup.string().required().min(8) to validate that our inputted value is a string with a minimum of 8 characters.

Form-Level Validation

We can also add form level validation with Vee-Validate 4.

For instance, we can write:

<template>
  <Form @submit="submit" :validation-schema="simpleSchema" v-slot="{ errors }">
    <Field name="email" as="input" />
    <span>{{ errors.email }}</span>
    <br />
    <Field name="password" as="input" type="password" />
    <span>{{ errors.password }}</span>
    <br />
    <button>Submit</button>
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
export default {
  components: {
    Field,
    Form,
  },
  data() {
    const simpleSchema = {
      email(value) {
        return /S+@S+.S+/.test(value) ? true : "email is not valid";
      },
      password(value) {
        return value || "password is required";
      },
    };
    return {
      simpleSchema,
    };
  },
  methods: {
    submit() {},
  },
};
</script>

We set the validation-schema to the simpleSchema object which has the validation functions for each field we want to validate.

The function names in simpleSchema should match the value of the name prop of the Field component.

Validation Schemas with Yup

We can add validation schemas with yup .

To do this, we write:

<template>
  <Form @submit="submit" :validation-schema="schema" v-slot="{ errors }">
    <Field name="email" as="input" />
    <span>{{ errors.email }}</span>
    <br />
    <Field name="password" as="input" type="password" />
    <span>{{ errors.password }}</span>
    <br />
    <button>Submit</button>
  </Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";
export default {
  components: {
    Field,
    Form,
  },
  data() {
    const schema = yup.object().shape({
      email: yup.string().required().email(),
      password: yup.string().required().min(8),
    });
    return {
      schema,
    };
  },
  methods: {
    submit() {},
  },
};
</script>

We create the schema object with the email and password properties, which match the name attribute values on the Field component.

We call the yup.object.shape method to create the schema with the email and password fields to do the validation for each field.

Conclusion

We can use the Yup library with Vee-Validate to validate our form fields.