VeeValidate Logo

Validations

The available validation rules

Syntax

The validation rules have a simple syntax similar to Laravel validation syntax.

A validation expression is a string of a series of validators separated by a pipe |:

const single = 'required'; // single rule.
const multiple = 'required|numeric' // multiple rules.

Rules can also take on an object form for complex and more readable rules:

const single = { required: true }; // required field.
const multiple = {
  required: true,
  numeric: true,
  email: true
};

Some rules can have parameters, which are passed in a comma separated list without spaces.

const someRule = 'in:1,2,3,4';
const someRuleObj = { in: [1, 2, 3, 4] };

In object form, rules keys accept a single value if the rule accepts a single argument. If multiple arguments are passed, you should pass them as an array in the same order.

Available Rules

There are more than 20 rules available to validate your inputs:

Date validators require the date_format rule to always be present (or globally set) and must preceed them in the rules order.

after:{target},{inclusion?}

The field under validation must have a valid date and is after the date value in the target field.

  • target: The input name to be validated against. Must have the same format as the date_format rule. Can also be a date value of the same format.
  • inclusion: Whether to include equal dates as a valid value, setting it to any value will set it to true, it is false by default.
{{ errors.first('after_field') }}

Target based rules like after, before, and confirmed can target custom components as well as native inputs, but when targeting custom components the target field must have a ref attribute set and the confirmed paramter must be the same ref value prefixed with $ sign to tell the validator that it should look for the target field in the component local refs. More information are in the RC.8 release notes.

alpha

The field under validation may only contain alphabetic characters.

{{ errors.first('alpha_field') }}

alpha_dash

The field under validation may contain alphabetic characters, numbers, dashes or underscores.

{{ errors.first('alpha_dash_field') }}

alpha_num

The field under validation may contain alphabetic characters or numbers.

{{ errors.first('alpha_num_field') }}

alpha_spaces

The field under validation may contain alphabetic characters or spaces.

{{ errors.first('alpha_spaces_field') }}

before:{target},{inclusion?}

The field under validation must have a valid date and is before the date value in the target field.

  • target: The input name to be validated against. Must have the same format as the date_format rule. Can also be a date value of the same format.
  • inclusion: Whether to include equal dates as a valid value, setting it to any value will set it to true, it is false by default.
{{ errors.first('before_field') }}

between:{min},{max}

The field under validation must have a numeric value bounded by a minimum value and a maximum value.

  • min: The minimum value.
  • max: The maximum value.
{{ errors.first('between_field') }}

confirmed:{target}

The field under validation must have the same value as the confirmation field.

  • target: The name of the confirmation field.
{{ errors.first('confirm_field') }}

credit_card

The field under validation must be a valid credit card.

{{ errors.first('credit_field') }}

date_between:{min,max},{inclusion?}

The field under validation must be a valid date between the two dates specified.

  • min:The minimum allowed value for date. Must be in the same format as the date_format rule.
  • max:The maximum allowed value for date. Must be in the same format as the date_format rule.
  • inclusion: Whether to include equal dates as a valid value, it is set to () (exclude) by default.
    (For further information check the monentjs inclusion docsvee-validate uses date-fns but ported this functionality.
{{ errors.first('date_between_field') }}

date_format:{format}

The field under validation must be a valid date in the specified format. This rule must be present when using any date rule.

{{ errors.first('date_format_field') }}

decimal:{decimals?}

The field under validation must be numeric and may contain the specified amount of decimal points.

  • decimals: The maximum allowed number of decimal point numbers. Not passing the decimals will accept numeric data which may or may not contain decimal point numbers.
{{ errors.first('decimal_field') }}

digits:{length}

The field under validation must be numeric and have the specified number of digits.

  • length: The number of digits.
{{ errors.first('digits_field') }}

dimensions:{width},{height}

The file added to the field under validation must be an image (jpg,svg,jpeg,png,bmp,gif) having the exact specified dimension.

  • width: The width of the image.
  • height: The height of the image.
{{ errors.first('dimensions_field') }}

email

The field under validation must be a valid email.

{{ errors.first('email_field') }}

ext:[extensions]

The file added to the field under validation must have one of the extensions specified.

  • extensions: Comma separated list of extensions. ex: `ext:jpg,png,bmp,svg
{{ errors.first('ext_field') }}

image

The file added to the field under validation must have an image mime type (image/*).

{{ errors.first('image_field') }}

in:[list]

The field under validation must have a value that is in the specified list.

  • list: Comma separated list of values. ex in:1,2,3
{{ errors.first('in_field') }}

ip

The field under validation must have a string that is a valid ipv4 value.

{{ errors.first('ip_field') }}

is:{value}

The field under validation must be equal to the first argument passed, uses === for equality checks. This rule is useful for confirming passwords when used in object form. Note that using the string format will cause any arguments to be parsed as strings, so use the object format when using this rule.

  • value: A value of anytype to be compared against the field value.
<input v-validate="{ is: confirmation }" type="text" name="password">
<input v-model="confirmation" type="text" name="password_confirmation">

max:{length}

The field under validation length may not exceed the specified length.

  • length: A numeric value representing the maximum number of characters.
{{ errors.first('max_field') }}

max_value:{value}

The field under validation must be a numeric value and must not be greater than the specified value.

  • value: A numeric value representing the greatest value allowed.
{{ errors.first('max_value_field') }}

mimes:[list]

The file type added to the field under validation should have one of the specified mime types.

  • list: List of comma separated mime types. mimes:image/jpeg,image/png

{{ errors.first('mimes_field') }}

You can use '*' to specify a wild card, something like mimes:image/* will accept all image types.

min:{length}

The field under validation length should not be less than the specified length.

  • length: A numeric value representing the minimum number of characters.
{{ errors.first('min_field') }}

min_value:{value}

The field under validation must be a numeric value and must not be less than the specified value.

  • value: A numeric value representing the lowest value allowed.
{{ errors.first('min_value_field') }}

not_in:[list]

The field under validation length should not have any value within the specified value.

  • list: Comma separated list of invalid values. ex: not_in:1,2,3
{{ errors.first('not_in_field') }}

numeric

The field under validation must only consist of numbers.

{{ errors.first('numeric_field') }}

regex:{pattern}

The field under validation must match the specified regular expression.

  • pattern: A regular expression
  • flags: list of regular expression flags (optional)

{{ errors.first('regex_field') }}

You should not use the pipe '|' or commas ',' within your regular expression when using the string rules format as it will cause a conflict with how validators parsing works. You should use the object format of the rules instead. Note that when using the object format in your HTML template, you need to escape all backslashes. Example: v-validate="{ required: true, regex: /\\.(js|ts)$/ }"

required:{invalidateFalse?}

The field under validation must have a non-empty value. By default, all validators pass the validation if they have "empty values" unless they are required. Those empty values are: empty strings, undefined, null.

By default, the boolean value of false will pass validate. Setting invalidateFalse to true will fail validation for false values. For example, using v-validate="'required:true'" is helpful to support pseudo-checkbox validations where the checkbox must be checked. Note that <input type='checkbox' v-validate="'required'" /> automatically supports this scenario.

{{ errors.first('required_field') }}

size:{kb}

The file size added to the field under validation must not exceed the specified size in kilobytes.

  • size: The maximum file size in kilobytes.
{{ errors.first('size_field') }}

url:{require_protocol?}

The field under validation must be a valid url. Protocols are not required by default.

  • require_protocol: If the protocol should be required. It's set to false by default. Passing anything will require it.
{{ errors.first('url_field') }}

Custom Rules

You can easily add custom rules to the validators, but your custom validation rules must adhere to a contract, or certain structure:

Function Form: This is the most basic custom validator form, it consists of only a function that returns either a Boolean or a promise. However, it will have a default error message.

const validator = (value, args) => {
  // Return a Boolean or a Promise.
};

Object Form:

const validator = {
  getMessage(field, args) {
    // will be added to default English messages.
    // Returns a message.
  },
  validate(value, args) {
    // Returns a Boolean or a Promise.
  }
};

This validator object must have a validate method, and can contain a getMessage method which will be merged into the current dictionary locale. For multiple languages, you should use the localization API.

Notice how the getMessage method receives the field which is the name of the field under validation as a first parameter. And how the validate method receives the value as a first parameter. And both receive the args array which contains the arguments that were configured with the validation rule. take a look at the actual implementation of the min rule as an example.

As you can see, a validation rule must implement one of the three forms discussed above. Not doing so will throw an exception with a suitable error message detailing what you were missing.

Additionally, you may want to provide a reason for failing the validation that may change the error message. For example, you may be using an external API and the error message is generated there.

To achieve this, you need to return an Object instead of a Boolean this object should always contain a valid property and an optional data property, the data property will be passed to the message generator function as the third parameter, then you should use the passed data property to modify the output message. The same thing applies to promises as you resolve the promise with an object containing those properties. Here is a custom rule that does just that:

const myRule = {
  getMessage(field, params, data) {
      return (data && data.message) || 'Something went wrong';
  },
  validate(value) {
    return new Promise(resolve => {
      resolve({
        valid: value === 'trigger' ? false : !! value,
        data: value !== 'trigger' ? undefined : { message: 'Not this value' }
      });
    });
  }
};

After creating your custom rule, you can add it to the list of rules using extend(name, validator) method in the validator instance.

import { Validator } from 'vee-validate';

Validator.extend('truthy', {
  getMessage: field => 'The ' + field + ' value is not truthy.',
  validate: value => !! value
});

let instance = new Validator({ trueField: 'truthy' });

// Also there is an instance 'extend' method for convience.
instance.extend('falsy', (value) => ! value);

instance.attach({
  name: 'falseField',
  rules: 'falsy'
});

Using any of the extend either on the class or on an instance will extend all validators with the new validation rule. Extending a new rule that has the same name as an existing rule will throw a ValidatorException with an error message.

Flags

vee-validate includes few flags that could help you improve your user experience, each field under validation has its own set of flags which are:

  • touched: indicates that the field has been touched or focused.
  • untouched: indicates that the field has not been touched nor focused.
  • dirty: indicates that the field has been manipluated.
  • pristine: indicates that the field has not been manipluated.
  • valid: indicates that the field has been validated at least once and that it passed the validation.
  • invalid: indicates that the field has been validated at least once and that it failed the validation.

The flags are reactive objects, so you can build computed properties based on them. For example, here is how you can tell if a form has been manipulated, say maybe to disable/enable a button.

export default {
  // ...
  computed: {
    isFormDirty() {
      return Object.keys(this.fields).some(key => this.fields[key].dirty);
    }
  },
  //...
}

The global fields flags are accessed via objects like this:

// Is the 'name' field dirty? 
this.fields.name.dirty;

However, for the scoped fields, the FieldBag will group those fields in an property name that is prefixed by a $ to indicate that it is a scope object:

// Is the 'name' field dirty? 
this.fields.$myScope.name.dirty;

// Is the 'name' field clean? 
this.fields.$myScope.name.pristine; 

Here is what it would look like:

<div class="form-input">
  <input type="text" name="email" v-validate="'required|email'" placeholder="Email">
  <span v-show="errors.has('field')">{{ errors.first('field') }}</span>
  <span v-show="fields.email && fields.email.dirty">I'm Dirty</span>
  <span v-show="fields.email && fields.email.touched">I'm touched</span>
  <span v-show="fields.email && fields.email.valid">I'm valid</span>
</div>
<div class="form-input">
  <input data-vv-scope="scope" type="text" name="email" v-validate="'required|email'" placeholder="Email">
  <span v-show="errors.has('scope.field')">{{ errors.first('scope.field') }}</span>
  <span v-show="fields.$scope && fields.$scope.email && fields.$scope.email.dirty">I'm Dirty</span>
</div>

Notice the additional checks before the actual flag check, this is because the flags aren't actually available until the mounted() life cycle event, so to avoid created() life cycle errors we need to add those checks.

This can become quite tedious if you are referencing multiple flags, so it might be useful to use the mapFields helper, which is similar to Vuex's mapGetters and mapActions as it maps a field object to a computed property.

import { mapFields } from 'vee-validate'

export default {
  // ...
  computed: mapFields(['name', 'email', 'scope.email']),
 // ...
}

You can also provide an object to rename the mapped props:

import { mapFields } from 'vee-validate'

export default {
  // ...
  computed: mapFields({
    fullname: 'name',
    phone: 'scope.phone'
  }),
 // ...
}

Note that scoped fields names in the array from is mapped to a non-nested name, and you can use the object spread operator to add the mapped fields to your existing computed components:

import { mapFields } from 'vee-validate'

export default {
  // ...
  computed: {
    ...mapFields(['name', 'email', 'scope.phone']),
    myProp() {
       // ....
    }
  },
 // ...
}

Additionally, in case you want to set the flags manually, you can use the Validator.flag(fieldName, flagsObj) method:

// flag the field as valid and dirty.
this.$validator.flag('field', {
  valid: false,
  dirty: true
});

// set flags for scoped field.
this.$validator.flag('scoped.field', {
  touched: false,
  dirty: false
});

For custom components, in order for the flags to fully work reliably, you need to emit those events:

The input event, which you probably already emit, will set the dirty and pristine flags.

this.$emit('input', value); 

// The focus event which will set the touched and untouched flags.
this.$emit('focus'); 

Here is an example that displays those flags, intereact with the input and watch the flags change accordingly:

import { mapFields } from 'vee-validate'; export default { name: 'flags-example', data: () => ({ email: '' }), computed: { ...mapFields({ nameFlags: 'name' }) } };
<div class="columns is-multiline"> <div class="column is-12"> <label class="label">Name</label> <p class="control has-icon has-icon-right"> <input name="name" v-validate="'required|alpha'" :class="{'input': true }" type="text" placeholder="Name"> </p> <pre>{{"{" + "{ nameFlags }" + "}"}}</pre> </div> </div>