Simple, lightweight model-based validation for Vue.js

Overview

vuelidate

codecov gzip size

Simple, lightweight model-based validation for Vue.js

Sponsors

Gold

Vuejs Amsterdam

Vue - The Road To Enterprise

Silver

Storyblok

Bronze

Vue Mastery logo Vue Mastery logo

Features & characteristics:

  • Model based
  • Decoupled from templates
  • Dependency free, minimalistic library
  • Support for collection validations
  • Support for nested models
  • Contextified validators
  • Easy to use with custom validators (e.g. Moment.js)
  • Support for function composition
  • Validates different data sources: Vuex getters, computed values, etc.

Demo & docs

https://vuelidate.js.org/

Vue 3 support

Vue 3 support is almost here with the Vuelidate 2 rewrite. Check out the next branch to see the latest progress.

Installation

npm install vuelidate --save

You can import the library and use as a Vue plugin to enable the functionality globally on all components containing validation configuration.

import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)

Alternatively it is possible to import a mixin directly to components in which it will be used.

import { validationMixin } from 'vuelidate'

var Component = Vue.extend({
  mixins: [validationMixin],
  validations: { ... }
})

The browser-ready bundle is also provided in the package.

<script src="vuelidate/dist/vuelidate.min.js">script>

<script src="vuelidate/dist/validators.min.js">script>
Vue.use(window.vuelidate.default)

Basic usage

For each value you want to validate, you have to create a key inside validations options. You can specify when input becomes dirty by using appropriate event on your input box.

import { required, minLength, between } from 'vuelidate/lib/validators'

export default {
  data () {
    return {
      name: '',
      age: 0
    }
  },
  validations: {
    name: {
      required,
      minLength: minLength(4)
    },
    age: {
      between: between(20, 30)
    }
  }
}

This will result in a validation object:

$v: {
  name: {
    "required": false,
    "minLength": false,
    "$invalid": true,
    "$dirty": false,
    "$error": false,
    "$pending": false
  },
  age: {
    "between": false
    "$invalid": true,
    "$dirty": false,
    "$error": false,
    "$pending": false
  }
}

Checkout the docs for more examples: https://vuelidate.js.org/

Contributing

# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# create UMD bundle.
npm run build

# Create docs inside /gh-pages ready to be published
npm run docs

# run unit tests
npm run unit

# run all tests
npm test

For detailed explanation on how things work, checkout the guide and docs for vue-loader.

Contributors

Current

Damian Dulisz
Damian Dulisz
Natalia Tepluhina
Natalia Tepluhina
Natalia Tepluhina
Dobromir Hristov
Marina Mosti
Marina Mosti

Emeriti

Here we honor past contributors who have been a major part on this project.

License

MIT

Comments
  • @types/vuelidate

    @types/vuelidate

    Provide types as inspired by #175.

    Main types:

    • Vuelidate = PluginFunction for Vue.use(Vuelidate)
    • ComponentOptions.validations
    • Vue.$v

    Some of the predefined predicates are covered, may be not all.

    opened by janesser 64
  • $v is not defined in single file component

    $v is not defined in single file component

    I'm trying to use the vuelidate plugin with my vue-router-enabled web app. I keep getting the following error:

    [Vue-warn]: Property or method "$v" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option

    This is my bootstrap file for reference:

    `import Vue from 'vue' import Resource from 'vue-resource' import App from "./components/App.vue" import router from "./router/appRouter.js" import store from "./store/appStore.js"

    Vue.use(Resource); Vue.use(Vuelidate);

    const app = new Vue({ el: '#app', router, store, render: (h) => h(App) }) `

    I'm using the plugin with the following code in component file:

    <template>
    <div>
        <div :class="'input-group ' + {'form-group-error': $v.email.$error }"> 
        <p class="label"> Email </p>
        <input type="text" id="email" v-model="models.email" @input="$v.email.$touch">
        </div>
    </div>
    </template>
    
    <script>
        const { required, minLength, alpha, email, numeric } = require("vuelidate/lib/validators");
        export default 
        {
            data(){...},
            methods:{...},
            etc
        }
    <script>
    

    I can't figure out how to reference $v in my code to allow the vue instance to access it. Sorry in advance if I'm missing something blindingly obvious but I've stuck on this for a while

    Thanks

    opened by shiningshisa 44
  • Validator 'numeric' only accepts positive integers

    Validator 'numeric' only accepts positive integers

    The name of the validator implies it is looking for any numeric value, including decimal and negative values. The current implementation only accepts positive integers. Either the accepted validation text should be broadened or this validator should be renamed.

    Example: https://jsfiddle.net/gregpeden/hmcLdc5a/

    I could provide a PR for this (fix this + provide actual integer test) if there is interest in changing it.

    opened by GregPeden 32
  • version of $dirty that is true if any children have been changed

    version of $dirty that is true if any children have been changed

    I would also like to have a value that is similar to $dirty with the difference being that it is true if any (rather than all) of the children are $dirty. The purpose to make it easy to track if there have been any changes in the overall form or a specific section of the form - e.g. certain actions will be available if even only one value has changed.

    I am just not sure how best to do this. I understand that $dirty is a computed value, so preferably I would like to add a complementary computed value to $dirty (e.g. $anydirty) to be access in a similar manner to the $dirty value. If anyone in the know has some guidance on the best way to achieve this it would be greatly appreciated.

    enhancement 
    opened by michaelsorich 27
  • Vuelidate does not work with vue 3

    Vuelidate does not work with vue 3

    An Error occurs as soon as I uncomment the following line:

    function useApplicationPluginsAndComponents (Application) { // Application.use(VueCompositionAPI) // causing error Application.use(router) Application.use(store) registerGlobalComponents(Application) return Application }

    Uncaught Error: [vue-composition-api] only works with Vue 2, v3.0.0-rc.3 found.

    Does vuelidate work with vue3?

    opened by tomisicm 25
  • Collection not required, but if present, subfield required

    Collection not required, but if present, subfield required

    Is it possible to define a rule where a collection is not required, but if it exists (eg a user chooses to add an item to the collection) then subfield(s) are required?

    I tried setting up a rule like this but got "TypeError: Cannot convert undefined or null to object" in console when the collection did not exist on certain records.

    bug 
    opened by Youdaman 24
  • Vite Vue TS intellisense error: Argument of type 'ComputedRef<>' is not assignable to parameter of type 'ValidationArgs<>'

    Vite Vue TS intellisense error: Argument of type 'ComputedRef<>' is not assignable to parameter of type 'ValidationArgs<>'

    Describe the bug I'm trying out vuelidate 2 alpha with typescript and vite, and there seems to be an issue with the typescript linter complaining about the types ComputedRef<{}> and ValidationArgs<{}>. I was following the instructions provided in making vuelidate rules, and I don't know why there's an error with typescript regarding the manner. Is there some sort of thing that I should've done that I don't know about? Like some sort of typecasting?

    Reproduction URL I apologise if I wasn't able to use the provided codesandbox templates provided, since the issue is on vite and not on vue-cli. Provided here is the URL of the code. The issue cannot be seen through codesandbox, and it will only be visible if you check the typescript linting on vscode itself. The file and line in question is on ./src/components/FormComposition.vue on ln 32.

    To Reproduce Steps to reproduce the behavior:

    1. Create a new vite project using the terminal using the vue-ts template: yarn create vite --template vue-ts vuelidate-issue-test.
    2. Open the project on VS Code.
    3. Open the VS Code inbuilt terminal and run yarn to initialise the project.
    4. Install vuelidate/core and vuelidate/validators onto the project: yarn add @vuelidate/core @vuelidate/validators.
    5. Create a new vue file component called Form.vue in src/components folder.
    6. Copy the code written below.
    // Form.vue
    
    <script lang="ts" setup>
    import { useVuelidate } from "@vuelidate/core";
    import { required, email, minLength, sameAs } from "@vuelidate/validators";
    import { reactive, computed } from "vue";
    
    const state = reactive({
      email: "",
      password: {
        pass: "",
        confirm: "",
      },
    });
    
    const rules = computed(() => {
      return {
        email: { required, email },
        password: {
          pass: { required, minLength: minLength(6) },
          confirm: { required, sameAs: sameAs(state.password.pass) },
        },
      };
    });
    
    // const rules = {
    //   email: { required, email },
    //   password: {
    //     pass: { required, minLength: minLength(6) },
    //     confirm: { required, sameAs: sameAs(state.password.pass) },
    //   },
    // };
    
    const v$ = useVuelidate(rules, state);
    
    const submitForm = () => {
      // vuelidate validation
      v$.value.$validate();
    
      // if success
      if (!v$.value.$error) {
        alert("Form Successfully Submitted!");
      }
      // // if fail
      // else {
      //   alert(
      //     "I'm sorry, you seem to not have filled all inputs. Please fill them up and try again."
      //   );
      // }
    };
    </script>
    
    <template>
      <div class="root">
        <h2>Create an Account</h2>
        <p>
          <input type="text" v-model="state.email" placeholder="Email" />
          <span v-if="v$.email.$error">
            {{ v$.email.$errors[0].$message }}
          </span>
        </p>
        <p>
          <input
            type="password"
            v-model="state.password.pass"
            placeholder="Password"
          />
          <span v-if="v$.password.pass.$error">
            {{ v$.password.pass.$errors[0].$message }}
          </span>
        </p>
        <p>
          <input
            type="password"
            v-model="state.password.confirm"
            placeholder="Confirm Password"
          />
          <span v-if="v$.password.confirm.$error">
            {{ v$.password.confirm.$errors[0].$message }}
          </span>
        </p>
        <button @click="submitForm">Submit</button>
      </div>
    </template>
    
    1. Go back to the App.vue file, and update the file as is:
    // App.vue
    
        <script setup lang="ts">
    -    // This starter template is using Vue 3 <script setup> SFCs
    -    // Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
    -    import HelloWorld from './components/HelloWorld.vue'
    +    import Form from './components/Form.vue'
        </script>
        
        <template>
    -      <img alt="Vue logo" src="./assets/logo.png" />
    -      <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
    +      <Form />
        </template>
    
        <style>
        #app {
          font-family: Avenir, Helvetica, Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
          text-align: center;
          color: #2c3e50;
          margin-top: 60px;
        }
        </style>
    
    1. Run the development server using yarn dev.

    Expected behavior There are no errors when running it in the development server, but the only issue is that the typescript linter is complaining about incompatible types.

    Screenshots where the typescript error shows up

    Additional context I was following a tutorial by LearnVue, and when I reached the section where the tutorial is converting the code from the options api to the composition api, and I stumbled upon on how to initialise the useVuelidate() method. When I tried doing it myself, the typescript lint `Argument of type 'ComputedRef<{email: required...}>' is not assignable to parameter of type 'ValidationArgs<{email: string;...}>'.

    bug 2.0 
    opened by cindrmon 23
  • Validation status is sometimes not evaluated in 0.4.1

    Validation status is sometimes not evaluated in 0.4.1

    https://jsfiddle.net/gLg17z9o/

    Try to click Validate => it turns to red. Now try to fill field - validation stays red.

    Fill field => it turns green. Clear field => it stays green.

    Replace

    {{$v.form.password.$error}}
    with
    {{$v.form.password}}
    Now everything works as expected.

    bug 
    opened by pdanpdan 23
  • Vue 2.6 + Composition API + Vuelidate

    Vue 2.6 + Composition API + Vuelidate

    Hey, I'm trying to use the next branch with Vue 2.6 and Composition API (in quasar framework), but it doesn't work, I got the following error :

    TypeError: Object(...) is not a function
        at useVuelidate (index.esm.js?dc83:580)
        at useRegisterForm (use-register-form.ts?f336:57)
    

    Quasar Framework is not yet shipped with Vue 3, so I tried the old version of Vuelidate, I export the validations object in the setup function but I think it has no effect as I can't find the $v object.

    import { reactive, toRefs, defineComponent } from '@vue/composition-api'
    import { api } from 'boot/axios'
    import {
      required,
      email,
      minLength,
      sameAs
    } from 'vuelidate/lib/validators'
    
    type Selected = {
      label: string,
      value: string | number
    }
    
    export default function useRegisterForm () {
      const state = reactive({
        lastName: '',
        firstName: '',
        email: '',
        address: '',
        password: '',
        passwordConfirmation: '',
        terms: false,
        dialCode: 0,
        zipCode: null,
        mobile: '',
        countries: [] as Array<Selected>,
        country: {
          label: null,
          value: null,
          iso: null,
          dial_code: null
        },
        states: [] as Array<Selected>,
        state: {
          label: null,
          value: null
        },
        cities: [] as Array<Selected>,
        city: {
          label: null,
          value: null
        }
      })
    
      const validations = {
        email: {
          required,
          email
        }
      }
    
      // METHODS
      async function onSubmit (): Promise<void> {
        try {
          const { data } = await api.post<Array<Record<string, any>>>('/register', {
            last_name: state.lastName,
            first_name: state.firstName,
            email: state.email,
            mobile: `+${state.dialCode}${state.mobile.replace(/\s/g, '')}`,
            country: state.country.value,
            state: state.state.value,
            city: state.city.value,
            address: state.address,
            zip_code: state.zipCode,
            password: state.password,
            password_confirmation: state.passwordConfirmation,
            terms: state.terms
          })
        } catch (e) {
        }
      }
    
      return {
        state,
        onSubmit,
        validations
      }
    }
    
    export default defineComponent({
        name: 'Register',
        setup (props, context) {
            const { state, onSubmit, validations } = useRegisterForm()
    
            return {
               ...toRefs(state as any),
               validations
          }
       }
    })
    

    I have no JS error. Any idea please?

    opened by Melchyore 22
  • TypeError: Cannot read property 'name' of undefined

    TypeError: Cannot read property 'name' of undefined

    Hey,

    I am also having some difficulty getting this to work, not sure where I am going wrong. Some guidance would be very much appreciated.

    app.js

    import Vue from 'Vue'
    import Vuelidate from 'vuelidate'
    import { required, alpha, email } from 'vuelidate/lib/validators'
    
    Vue.use(Vuelidate)
    
    new Vue({
      el: '#form',
      data: {
        name: '',
        email: '',
      },
      validations: {
        name: {
          required,
          alpha,
        },
        email: {
          required,
          email,
        },
      },
    })
    

    Here is my html

    <form id="form">
    
    <input type="text" placeholder="Name" v-model="name" name="name">
    <span v-if="!$v.name.alpha">Please enter a valid name.</span>
    
    <input type="text" placeholder="Email" v-model="email" name="email">
    <span v-if="!$v.email.email">Please enter a valid email.</span>
    
    </form>
    

    When I try to output {{ $v }} I get nothing either.

    opened by baconjulie 21
  • Message Params

    Message Params

    name: {
      required,
      minLength: minLength(6)
      maxLength: withMessage(maxLength, 10)
    }
    
    function withMessage (rule, ...args) {
      const wrapRule = rule(...args)
      wrapRule.messageParams = () => args
      return wrapRule
    }
    
    function required (x) {
      return !!x
    }
    
    required.messageParams (x) {
      return
    }
    
    enhancement 
    opened by shentao 21
  • $each does not work on non-objects

    $each does not work on non-objects

    Describe the bug $each is responsible for evaluating collections. The new documentation says to use the helpers.forEach. The example in the docs uses an array of objects, but when I try to apply it to non-objects such as strings / numbers it does not work.

    Reproduction URL The sandbox tries to evaluate the array of strings, but it doesn't pick up that anything is wrong.

    Vuelidate 2 - Options API + Vue 3

    To Reproduce Steps to reproduce the behavior:

    1. Add "not an email" to the input field
    2. Click on 'Add'
    3. See that the array is valid

    Expected behavior The array should be invalid.

    Additional context Regarding the code sandbox. i know i can validate the email before it gets added.

    bug 2.0 
    opened by BennieVE 0
  • Vuelidate 2.x + Vue 3 + Typescript Nested Objects type checking

    Vuelidate 2.x + Vue 3 + Typescript Nested Objects type checking

    So, I'm using vuelidate with typescript for a while, found no problem at all, it the intellisense and type checking works just fine, but i've just found an edge case where, it doesn't seem to work quite well. When using vuelidate with nested objects, the returned v$ from the useVuelidate function doesn't list the nested objects properties.

    image image

    When I log the value of v$, the nested properties are indeed listed.

    Is there a way around it, or am I doing it incorrectly?

    opened by Brunnn 0
  • Update guide.md

    Update guide.md

    Summary

    Used the correct "its" (possessive, not contraction)

    Metadata

    What kind of change does this PR introduce? (check at least one)

    • [ ] Bugfix
    • [ ] Feature
    • [ ] Code style update
    • [ ] Refactor
    • [ ] Build-related changes
    • [x] Other, please describe: docs typo

    Does this PR introduce a breaking change? (check one)

    • [ ] Yes
    • [x] No

    If yes, please describe the impact and migration path for existing applications:

    The PR fulfills these requirements:

    • [x] I have read the Contribution Guides
    • [x] It's submitted to the next branch
    • [x] When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)
    • [x] All tests are passing: https://github.com/vuelidate/vuelidate/blob/master/.github/CONTRIBUTING.md#development-setup
    • [x] New/updated tests are included

    If adding a new feature, the PR's description includes:

    • [x] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

    Other information:

    opened by llamington 0
  • Add async validation examples in docs

    Add async validation examples in docs

    Hello

    How make async validating?

    https://vuelidate-next.netlify.app/examples.html#asynchronous-validation Whats response should be? If true/false, then not working

    https://vuelidate-next.netlify.app/custom_validators.html#async-validators How add message?

    for example:

    const rules = {
        attributeLabel: { required: helpers.withMessage('Please input your Attribute Label', required) },
        attributeId: {
          required: helpers.withMessage('Please input your Attribute ID', required),
          async unique(value: string) {
            if (value === '') return true;
            const response = await fetch(`/api/unique/${value}`);
            const { isUnique } = await response.json();
            return isUnique ? {
              $message: 'test',
            } : true;
          },
        },
    

    Give me please one workable example with an async function and custom message

    bug 2.0 
    opened by AndreiSoroka 1
  • Question: How to use two separate validations (one lazy and one not) for the same model?

    Question: How to use two separate validations (one lazy and one not) for the same model?

    I have a name field that is validated non-lazily with the required rule:

    const rules = {
      name: { required }
    }
    

    I need to add another validation (e.g. custom one) that will check if name is unique among a collection of names and this will be done on demand, i.e. when the user clicks on the primary action on the form. Therefore I need a 2nd validation for name which would be lazy and which I would check on primary action.

    How can I configure my rules which I pass to useVuelidate to have these 2 validations for name?

    opened by ddenev 0
  • fix #1115 - enhance types

    fix #1115 - enhance types

    Summary

    Enhance types of ValidationRule, helpers.withParams and helpers.regex

    fixes #1115

    Metadata

    What kind of change does this PR introduce? (check at least one)

    • [ ] Bugfix

    • [ ] Feature

    • [ ] Code style update

    • [ ] Refactor

    • [ ] Build-related changes

    • [x] Other, please describe: Only added some types Does this PR introduce a breaking change? (check one)

    • [ ] Yes

    • [x] No

    If yes, please describe the impact and migration path for existing applications:

    The PR fulfills these requirements:

    • [x] I have read the Contribution Guides
    • [x] It's submitted to the next branch
    • [x] When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)
    • [x ] All tests are passing: https://github.com/vuelidate/vuelidate/blob/master/.github/CONTRIBUTING.md#development-setup
    • [ ] New/updated tests are included

    If adding a new feature, the PR's description includes:

    • [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

    Other information:

    opened by ig-onoffice-de 1
Releases(@vuelidate/[email protected])
Simple, lightweight, isomorphic, and template-based validation library.

Simple, lightweight, isomorphic, template-based validation.

Arnaud Gissinger 2 Dec 9, 2021
Vue data validation rules, very much inspired from Laravel validation

A Vue plugin that provides out-of-the-box data validation rules, very much inspired from Laravel validation system. Installation npm i @primitivesocia

Primitive. 15 Apr 13, 2022
Vue props validation logic extracted for nested validation in object and arrays.

vue-props-validation Vue props validation logic extracted for nested validation in object and arrays. Install npm install vue-props-validation Usage Y

Rubén Valseca 21 Feb 28, 2022
Form Validation in Vue3 with TypeScript along with vuelidate for the validation

Vue3 with typescript Form Validation in Vue3 with vuelidate library Node Version Used: v14.17.3 Library Used for the validation: Vuelidate 2 Demo Link

Sandeep Kumar Mandal 4 Oct 10, 2022
Sirius Validation - stand-alone JS library for data validation in Node and browsers.

SiriusJS Validation Sirius Validation is stand-alone JS library for data validation in Node and browsers. It offers: 23 build-in validation rules. The

Adrian Miu 1 Mar 24, 2020
Fast, lightweight validation with full typescript support for Vue 3

OtterValidationVue Fast, lightweight validation with full typescript support for Vue 3 OtterValidationVue is a Vue 3 wrapper for OtterValidation Insta

Johannes Vogt 0 Apr 24, 2021
vaLittle - Lightweight validation plugin in pure js

vaLittle Lightweight validation plugin in pure js Example of ussage: VUE In main.js add these lines import vaLittle from 'vue-valittle' Vue.use(va

Jacek 0 Nov 3, 2021
Model forms as an immutable data tree with validators and an explicit dirty/pristine state

Model your form as an immutable data tree with validators and an explicit dirty/pristine state.

Ben Blackmore 18 Feb 14, 2022
Vee-validate: a template-based validation framework for Vue.js that allows you to validate inputs and display errors.

vee-validate is a template-based validation framework for Vue.js that allows you to validate inputs and display errors. Being template-based you only

Eugene Strukov 0 Feb 28, 2020
✔ Template Based Validation Framework for Vue.js

vee-validate is a template-based validation framework for Vue.js that allows you to validate inputs and display errors.

Arnaldo Trujillo Falcón 0 Sep 1, 2019
Simple package to display error in vue from laravel validation

Laravel Vue Validator By bubbleflat.com This package allow to display errors from laravel validation rules ! This package needs vue-resource to work !

Valentin Vivies 32 Sep 20, 2020
A simple way to handle Laravel back-end validation in Vue 2.

vform A simple way to handle Laravel back-end validation in Vue. Inspired from Laravel Spark. Installation npm i axios vform Usage See the included ex

Cretu Eusebiu 603 Nov 22, 2022
Simple Vue.js form validation library

Simple Vue.js form validation library

null 0 Mar 1, 2020
A simple vue component that can wrap forms with validation and submit functionality.

vue form component A simple vue component that can wrap forms with validation and submit functionality. installation Using npm: $ npm i -save-dev vue-

Kostas Tourvas 0 Sep 18, 2019
Simple and easy Vue directive for form validation.

Simple and easy Vue.js directive for form validation.

Edward S. Ramos 0 Feb 15, 2021
Deadly simple form validation for Vue.js

vue-form-validator Deadly simple form validation for Vue.js. Features: Built in data types, including email, number, domain, url, etc. Customizable va

Wenbo 10 Aug 28, 2018
Vue Laravel Validator This plugin handle laravel validation response and simple creating form and posting data

Vue Laravel Validator This plugin handle laravel validation response and simple creating form and posting data. #install npm i vue-laravel-validator -

Metin Seylan 58 Aug 23, 2022
simple, powerful, vuejs validation.

Vuelidation ✅ simple, powerful, vuejs validation. ✨ Example ✨ Install yarn add --dev [email protected] Include Plugin import Vue from 'vue'; import V

CJ Lazell 37 Jan 3, 2022
Vue.js form validation plugin that depends on the property not the HTML element on validating with no dependency and respect to Vue reactivity.

Vue.js form validation plugin that depends on the property not the HTML element on validating with no dependency and respect to Vue reactivity.

Mohammed Al-Mahdawi 1 May 7, 2019