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>
<!-- The builtin validators is added by adding the following line. -->
<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
  • Can't add external results with Composition API

    Can't add external results with Composition API

    opened by louis-kevin 0
  • docs: Some clarifications and cleanups

    docs: Some clarifications and cleanups

    Summary

    Just some clarifications on version requirements and v$ usage I noticed while browsing the docs. See the individual commit messages for details.

    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

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

    • [ ] Yes
    • [x] No

    Other information:

    opened by FichteFoll 1
  • How should Vuelidate be initialised when testing with Vitest?

    How should Vuelidate be initialised when testing with Vitest?

    The v$ object is not initialised correctly when a component is tested with Vitest. I have a very simple component with a checkbox bound to formData.accepted

      validations () {
        return {
          formData: {
            accepted: {
              required,
              sameAs: sameAs(true)
            }
          }
        }
      }
    

    Vuelidate is initialised within the component as per the docs

      setup () {
        return {
          v$: useVuelidate({ $autoDirty: true })
        }
      },
    

    When I run the following test under Jest, it passes

      it('click save button', async () => {
        const wrapper = mount(MyComponent)
    
        expect(wrapper.vm.v$.formData.accepted.$invalid).toBeTruthy()
        await wrapper.find('[data-cy="accept-checkbox"]').trigger('click')
        expect(wrapper.vm.v$.formData.accepted.$invalid).toBeFalsy()
      })
    

    However, if I run the same test using Vitest it fails because wrapper.vm.v$.formData is undefined because v$ is incorrectly initialised to:

    v$ {
      "$dirty": false,
      "$path": "__root",
      "$model": null,
      "$error": false,
      "$errors": [],
      "$invalid": false,
      "$anyDirty": false,
      "$pending": false,
      "$silentErrors": [],
      "$validationGroups": {}
    }
    

    By contrast, when the Jest test is run, v$.$silentErrors is not empty, and the following property path returns a value

    v$.formData.accepted.$invalid 
    

    What should I do to ensure that v$ is initialised correctly when the test is run with Vitest?

    Dependencies

    • Vue 2.7.14
    • Vuelidate 2.0.0
    opened by donalmurtagh 0
  • Error withAsync Method: TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.

    Error withAsync Method: TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.

    Make sure that you are familiar with documentation before submitting an issue.

    https://vuelidate.netlify.com/

    Describe the bug I want to validate image ratio before uploading to the database, but i got error like bellow when implementing validation using async method.

    export const fileRatioValidator = () =>
      helpers.withAsync(async (value: File) => {
        const url = URL.createObjectURL(value)
        const isSquare = new Promise((resolve, reject) => {
          const img = new Image()
          img.addEventListener('load', () => {
            resolve(img.width / img.height === 1)
          })
          img.addEventListener('error', err => {
            reject(err)
          })
          img.src = url
        })
        return await isSquare
      })
    

    Screenshots Screen Shot 2022-12-08 at 11 26 09

    bug 0.x 
    opened by safeimuslim 1
  • Nuxt 3 Support

    Nuxt 3 Support

    Describe the bug I tryied to use Vuelidate for Vue 3 in Nuxt 3.0.0 (stable version), and i got some error in my console when i tried to install these packages:

    npm install @vuelidate/core @vuelidate/validators

    I got these errors:

    npm ERR! Could not resolve dependency: npm ERR! dev @vuelidate/core@"^2.0.0" from the root project npm ERR! npm ERR! Conflicting peer dependency: [email protected] npm ERR! node_modules/vue npm ERR! peer vue@">= 2.5 < 2.7" from @vue/[email protected] npm ERR! node_modules/@vue/composition-api npm ERR! peerOptional @vue/composition-api@"^1.0.0-rc.1" from @vuelidate/[email protected] npm ERR! node_modules/@vuelidate/core npm ERR! dev @vuelidate/core@"^2.0.0" from the root project

    To Reproduce Create a new Nuxt 3 project and try to install Vuelidate

    Expected behavior Vuelidate works on Nuxt 3

    Anyone could help-me? I don't know if i'm doing something incorrect or somenting like this.

    bug 2.0 
    opened by hamonCordova 4
  • Missing validations in custom UI library components.

    Missing validations in custom UI library components.

    *edited for more concise post.....original and more detailed post is mirrored here: https://stackoverflow.com/questions/74695360/vue-2-and-vuelidate-2-validating-a-child-component-from-a-custom-npm-component

    Context:

    • I am building a reusable Vue component library with built-in Vuelidate validations; with the aim of triggering / validating components when they are used in other projects (for example I am now using them in a Vue 2.7 app).
    • Vuelidate is peerDependency and not bundled with the component library.
    • Vuelidate and validation works as expected when developing / prototyping with Storybook and Jest.
    • NPM bundling jsconfig: "compilerOptions": { "target": "es5", "module": "esnext"}
    • I've set up Vuelidate exactly the same way in my Vue app (front end app) and in Storybook (prototyping and developing app).

    Issue:

    • Components do not validate in Vue 2.7 app, as they typically would when testing in Storybook and Jest (before library compilation).

    Expected behavior:

    • Vuelidate validating reusable library components when used in other projects.

    image

    image

    • The "value" (coloured in red) is a property within the validations() hook / object, which disappears when the reusable component is used in Vue projects.
    bug 2.0 
    opened by mtkwebdev 0
Releases(@vuelidate/[email protected])
✅ Form Validation for Vue.js

vee-validate is a form validation library for Vue.js that allows you to validate inputs and build better form UIs in a familiar declarative style or u

Abdelrahman Awad 9.4k Dec 26, 2022
Jenesius vue modal is simple library for Vue 3 only

Jenesius Vue Modal Jenesius vue modal is simple library for Vue 3 only . Site Documentation Installation npm i jenesius-vue-modal For add modals in yo

Архипцев Евгений 63 Dec 30, 2022
Lightweight UI components for Vue.js based on Bulma

Buefy is a lightweight library of responsive UI components for Vue.js based on Bulma framework and design. Features Keep your current Bulma theme / va

Buefy 9.4k Jan 8, 2023
A lightweight Vue.js UI library with a simple API, inspired by Google's Material Design.

Keen UI Keen UI is a Vue.js UI library with a simple API, inspired by Google's Material Design. Keen UI is not a CSS framework. Therefore, it doesn't

Josephus Paye II 4.1k Jan 2, 2023
:tada: A magical vue admin https://panjiachen.github.io/vue-element-admin

English | 简体中文 | 日本語 | Spanish SPONSORED BY 活动服务销售平台 客户消息直达工作群 Introduction vue-element-admin is a production-ready front-end solution for admin inter

花裤衩 80.1k Dec 31, 2022
:eyes: Vue in React, React in Vue. Seamless integration of the two. :dancers:

vuera NOTE: This project is looking for a maintainer! Use Vue components in your React app: import React from 'react' import MyVueComponent from './My

Aleksandr Komarov 4k Dec 30, 2022
🎉 基于 vite 2.0 + vue 3.0 + vue-router 4.0 + vuex 4.0 + element-plus 的后台管理系统vue3-element-admin

vue3-element-admin ?? 基于 Vite 2.0 + Vue3.0 + Vue-Router 4.0 + Vuex 4.0 + element-plus 的后台管理系统 简介 vue3-element-admin 是一个后台前端解决方案,它基于 vue3 和 element-plu

雪月欧巴 84 Nov 28, 2022
A template repository / quick start to build Azure Static Web Apps with a Node.js function. It uses Vue.js v3, Vue Router, Vuex, and Vite.js.

Azure Static Web App Template with Node.js API This is a template repository for creating Azure Static Web Apps that comes pre-configured with: Vue.js

Marc Duiker 6 Jun 25, 2022
Mosha-vue-toastify - A light weight and fun Vue 3 toast or notification or snack bar or however you wanna call it library.

Mosha Vue Toastify A lightweight and fun Vue 3 toast or notification or snack bar or however you wanna call it library. English | 简体中文 Talk is cheap,

Baidi Liu 187 Jan 2, 2023
A plugin that can help you create project friendly with Vue for @vue/cli 4.5

vue-cli-plugin-patch A plugin that can help you create project friendly with Vue for @vue/cli 4.5. Install First you need to install @vue/cli globally

null 2 Jan 6, 2022
Veloce: Starter template that uses Vue 3, Vite, TypeScript, SSR, Pinia, Vue Router, Express and Docker

Veloce Lightning-fast cold server start Instant hot module replacement (HMR) and dev SSR True on-demand compilation Tech Stack Vue 3: UI Rendering lib

Alan Morel 10 Oct 7, 2022
Lightweight Mobile UI Components built on Vue

Vant Mobile UI Components built on Vue ?? 文档网站(国内) ?? 文档网站(GitHub) ???? 中文版介绍 Features 65+ Reusable components 1kb Component average size (min+gzip) 9

有赞 20.7k Dec 31, 2022
Everything you wish the HTML