VeeValidate Logo


Classes Public API

v-validate Directive

The v-validate directive is the main way to validate your inputs, the directive accepts either a string or an object as a value.

If a string was passed, it must be a valid rules string, that is the validation rules separated by pipes '|'.

  <input v-validate="'required|email'" name="field" type="text">

If an object was passed, it must contains properties of the rules to be used and the value would be their params in an array or a single value if it accepts a single parameter.

// String
const expression = 'required|regex:^[0-9]+';

const expression = {
  // parameterless rules take a boolean value.
  required: true,
  // single parameter rules take a single value.
  regex: /.(js|ts)$/,
  // multiple paramter rules take a single array.
  in: [1, 2, 3]


The directive also accepts an arg, that denotes the name of the vue model to validate, or a computed property.

  <input v-model="email" v-validate:email="'required|email'" name="field" type="text">
export default {
  data: () => ({
    email: ''

However the arg is entirely optional. Additionaly, v-validate checks if the input/component has v-model assigned to it, and treats that expression as the arg. But keep in mind that the arg must be a simple dot notation string, and it must be present on the vue instance.

You might ask when to use arg at all? since v-model can be detected. A valid situation is when you need to validate a computed property.


You can use .initial modifier to force the validation of the field initial value.

  <input v-model="email" v-validate.initial="'required|email'" name="field" type="text">
export default {
  data: () => ({
    email: ''

data-* Attributes

data-* attributes provide an alternate interface for the plugin to specify what exactly should happen, providing a simple and Vue version-compatiable API. They are useful if you do not like to pass complex expressions to the directive.

Attribute Description
data-vv-as Specifies a pretty name for the field.
data-vv-delay Specifies the delay amount in milliseconds for triggering the validation.
data-vv-name Specifies a name for the field, used in components validation and as a fallback name for inputs.
data-vv-value-path Specifies the value path within a component $data to retrieve the component current value. Only used for components.
data-vv-validate-on Used to specify a list of event names separated by pipes, the default varies by the type of the input.

The field must always have either a name or a data-vv-name attribute, either of which acts as the identifier for that input. The name attribute takes precedence. However, the name that appears in the error messages can be customized using the data-vv-as attribute or it can use the dictionary object

Rendering Errors

Naturally, you would want to display the errors to your users. The plugin augments your Vue instance with a private validator object and a public errors data object. You are responsible for how the errors should be rendered.

The errors object exposes simple methods to help you render errors:

  • first('field') Fetches the first error message associated with that field.
  • collect('field') Fetches all error messages associated with that field. Alternatively, you can pass nothing and it will return errors grouped by fields.
  • has('field') Checks if there are any errors associated with that field.
  • all() Gets all error messages.
  • any() Checks if there are any errors.

There are a few more methods that you can use to manipulate the errors object.


The single error structure looks like this:

const error = {
  field: 'Field name',
  msg: 'Error message',
  rule: 'Rule Name', // optional
  scope: 'Scope Name', // optional
  id: 'uniqueId' // optional

The ErrorBag class is a wrapper around an array - a collection object -, it is standalone and has no dependencies, you can use it in your code for any purpose:

import { ErrorBag } from 'vee-validate';

const bag = new ErrorBag();

// For example, you may want to add an error related to authentication:
bag.add('email', 'Wrong Credentials', 'auth');

// Display it like this:
Method Params Return Description
add {error Object} void Adds an error to the error bag, the error object must conform the object signature mentioned above.
all {String scope?} Array Gets all error messages in an array, specifying a scope will retrieve the messages within that scope.
any {String scope?} Boolean Checks if any errors exist, specifying a scope will limit the check to within that scope.
clear {String scope?} undefined Clears (removes) all errors, specifying a scope will remove errors only associated with that scope.
collect {String name?},{String scope?}, {Boolean mapped?} Array|Object Collects errors associated with a specific field. Not passing the field name will group all errors by field name instead. Specifying a scope will limit the collecting behavior to a specific scope. You can optionally specify if the errors objects should be mapped to error messages or not, providing false will return objects containing the full information about the error.
count Number Returns the number of errors that are currently in the collection.
first {String field|selector}, {String scope?} String Returns the first error message associated with a specific field or specified by the selector, providing a scope will look for messages within that scope.
firstById {String id} String Returns the first error message for a field with the given id.
firstByRule {String field}, {String rule}, {String scope?} String Returns the first error message associated with a specific field and rule, providing a scope will look for messages within that scope.
has {String field|selector}, {String scope?} Boolean Checks if there is an error message associated with a specific field or specified by the selector, providing a scope will check for messages within that scope.
remove {String field}, {String scope?} void Removes all errors associated with a specific field, specifying a scope will remove messages only for that field and scope.
update {String id}, {Object diff} void Updates a specific field's erorr messages data, used internally to keep field errors scope up to date.


Adding Fields

The validator is injected to the Vue instance as $validator automatically. However, it is also a standalone class and can be used separately for programmatically validating values. The constructor can optionally take an object to map each field name to a set of validations.

import { Validator } from 'vee-validate';
const validator = new Validator({
  email: 'required|email',
  name: 'required|alpha|min:3'

// Or

But you can construct the object without passing anything and add the validation rules later, using the attach method which takes FieldOptions as its first parameter.

import { Validator } from 'vee-validate';
const validator = new Validator();

validator.attach({ name: 'email', rules: 'required|email' }); // attach field.
 // attach field with display name for errors generation.
validator.attach({ name: 'name', rules: 'required|alpha', alias: 'Full Name' });

validator.detach('email'); // you can also detach fields.


After that, you can validate values with validate(field, value) which returns a promise that resolves to a boolean.

validator.validate('email', '').then(result => {
  console.log(result);  // true

validator.validate('email', 'foo@bar').then(result => {
  console.log(result); // false

You can validate multiple values at the same time using validateAll(obj):

validator.validateAll({ email: '', name: 'John Snow' }).then(result => {
  if (!result) {
    // validation failed.
  // success stuff.
}).catch(() => {
  // something went wrong (non-validation related).

Returns a Promise The ErrorBag will be populated with any errors encountered, throws if any error has been encountered. You can access the errors property directly which is an instance of the ErrorBag.

const errorBag = validator.errors;

The more options you provide to attach method, the greater the field capabilities increase. For example, providing a getter function option will allow the validator the find the field value whenever it needs to. So you will be able to call validateAll and validate without having to provide any values.


Most of these options are being handled by the v-validate directive and are provided for you automatically.


The validator instance can only generate messages for one locale at a time. But you need to use localize method or set the locale property to switch the validator locale.

validator.locale = 'ar';

All validators share the same locale configuration. So any locale changes will update all validator instances across your app. For more information about how to overwrite messages and add new ones, please refer to the custom messages section.

import { Validator } from 'vee-validate'; 

// Also exposed on the class.
Validator.localize('ar'); // Set all validator locales to 'ar'.

Validator.create().locale; // 'ar';

Checkout the full API at GitHub

Validator Example

Here is an example of using the validator without the directive, which means you will be responsible for monitoring input changes on your own, and calling the API methods as you see fit. This example uses a Vue instance to simplify things, but it can be used in plain JavaScript as well.

import { Validator } from 'vee-validate'; export default { name: 'validator-example', validator: null, data() { return { email: '', name: '', errors: null }; }, watch: { email(value) { this.validator.validate('email', value); }, name(value) { this.validator.validate('name', value); } }, methods: { validateForm() { this.validator.validateAll({ email:, name: }).then((result) => { if (result) { // eslint-disable-next-line console.log('All is well'); return; } // eslint-disable-next-line console.log('Oops!'); }); }, clearErrors() { this.errors.clear(); } }, created() { this.validator = new Validator({ email: 'required|email', name: 'required|alpha|min:3' }); this.$set(this, 'errors', this.validator.errors); } };
<div class="columns is-multiline"> <div class="column is-12"> <label class="label">Email</label> <p class="control has-icon has-icon-right"> <input v-model="email" name="email" :class="{'input': true, 'is-danger': errors.has('email') }" type="text" placeholder="Email"> <i v-show="errors.has('email')" class="fa fa-warning"></i> <span v-show="errors.has('email')" class="help is-danger">{{"{" + "{ errors.first('email') }" + "}"}}</span> </p> </div> <div class="column is-12"> <label class="label">Name</label> <p class="control has-icon has-icon-right"> <input v-model="name" name="name" :class="{'input': true, 'is-danger': errors.has('name') }" type="text" placeholder="Name"> <i v-show="errors.has('name')" class="fa fa-warning"></i> <span v-show="errors.has('name')" class="help is-danger">{{"{" + "{ errors.first('name') }" + "}"}}</span> </p> </div> <div class="column is-12"> <p class="control"> <button class="button is-primary" @click="validateForm" type="button" name="button">Validate All</button> <button class="button is-danger" @click="clearErrors" type="button" name="button">Clear</button> </p> </div> </div>