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 seperated by pipes '|'.

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

If an object was passed it must contain a rules property which can be either a rule string like above or an object, here is the valid directive expression values:

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

// Object with rules as string.
const expression = {
  rules: 'required|regex:^[0-9]+', // required
  scope: 'myscope', // optional
  arg: 'form.email' // optional

// Object with rules as object.
const expression = {
  rules: {
    // 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] 
  scope: 'myscope', // optional
  arg: 'from.email' // optional

// You can omit the omit nesting the rules in a property if you don't
// need to provide other options.
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.

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

However the arg is entirly 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.

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-rules [deprecated] Specifies the list of validations to be run against the field value.
data-vv-value-path Specifies the value path within a component $data to retrive the component current value. Only used for components.
data-vv-validate-on Used to specify a list of event names seperated by pipes, the default varies by the type of the input


The single error must look like this:

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

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 reason:

import { ErrorBag } from 'vee-validate';

const bag = new ErrorBag();

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

// Display it like this:
Method Params Return Description
add {String field}, {String msg}, {String ruleName}, {String scope?} undefined Adds an error to the errors object.
all {String scope?} Array Gets all error messages in an array, specifying a scope will retrive 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.
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?} undefined Removes all errors associated with a specific field, specifying a scope will remove messages only for that field and scope.


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.

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

validator.attach('email', 'required|email'); // attach field.
validator.attach('name', 'required|alpha', { prettyName: 'Full Name' }); // attach field with display name for error generation.
validator.detach('email'); // you can also detach fields.

After that you can validate values with validate(field, value) which should return a boolean if all validations pass. Like this:

validator.validate('email', 'foo@bar.com'); // true
validator.validate('email', 'foo@bar'); // false

Most validators return a Boolean, however some validators (very few) return a Promise The validator is aware of this and will only return a Promise if at least one validation yields a promise. the promise is resolved to boolean which you can later chain to check your fields.

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

validator.validateAll({ email: 'foo@bar.com', name: 'John Snow' }).then(() => {
  // success stuff.
}).catch(() => {
  // validation failed stuff

Returns a Promise The ErrorBag will be populated with any errors encountered, Throws if any error has been encountered. You can access the errorBag property directly or using getErrors().

var errorBag = validator.errorBag;
// or
var errorBag = validator.getErrors();

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


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.setLocale('ar'); // Set all validator locales to 'ar'.

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

Validator.setLocale(); // resets to english because no argument was passed, all validators will be switched to English.

Check 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: () => ({ 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: this.email, name: this.name }); }, clearErrors() { this.errors.clear(); } }, created() { this.validator = new Validator({ email: 'required|email', name: 'required|alpha|min:3' }); this.$set(this, 'errors', this.validator.errorBag); } };
<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>