✅ Form Validation for Vue.js

Overview

codecov circleci CDNJS npm npm Bundle Size Average time to resolve an issue Percentage of issues still open


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 using composition functions

Features

  • 🍞 Easy: Declarative validation that is familiar and easy to setup
  • 🧘‍♀️ Flexible: Synchronous, Asynchronous, field-level or form-level validation
  • ⚡️ Fast: Build faster forms faster with intuitive API and small footprint
  • 🏏 Minimal: Only handles the complicated and painful form concerns, gives you full control over everything else
  • 🍤 Tiny: Small footprint < 5kb which makes your apps faster to load
  • 😎 UI Agnostic: Works with native HTML elements or your favorite UI library components
  • 🦾 Progressive: Works with any setup whether you use Vue.js as a progressive enhancement or in a complex setup
  • ✅ Built-in Rules: Companion lib with 25+ Rules that covers most needs in most web applications
  • 🌐 i18n: 45+ locales for built-in rules contributed by developers from all over the world

Getting Started

Installation

# install with yarn
yarn add [email protected]

# install with npm
npm install [email protected] --save

Vue version support

The main v4 version supports Vue 3.x only, for previous versions of Vue, check the following the table

vue Version vee-validate version Documentation Link
2.x 2.x or 3.x v2 or v3
3.x 4.x v4

Usage

Declarative Components (Recommended)

Higher-order components are better suited for most of your cases. Register the Field and Form components and create a simple required validator:

import { Field, Form } from 'vee-validate';

export default {
  components: {
    Field,
    Form,
  },
  methods: {
    isRequired(value) {
    return value ? true : 'This field is required';
  },
};

Then use the Form and Field components to render your form:

<Form v-slot="{ errors }">
  <Field name="field" :rules="isRequired" />

  <span>{{ errors.field }}</span>
</Form>

The Field component renders an input of type text by default but you can control that

Composition API

If you want more fine grained control, you can use useField function to compose validation logic into your component:

import { useField } from 'vee-validate';

export default {
  setup() {
    // Validator function
    const isRequired = value => (value ? true : 'This field is required');
    const { value, errorMessage } = useField('field', isRequired);

    return {
      value,
      errorMessage,
    };
  },
};

Then in your template use v-model to bind the value to your input and display the errors using errorMessage:

<input name="field" v-model="value" />
<span>{{ errorMessage }}</span>

📚 Documentation

Read the documentation and demos.

Contributing

You are welcome to contribute to this project, but before you do, please make sure you read the contribution guide

Credits

Emeriti

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

⚖️ License

MIT

Comments
  • Prevent creation of $validator on every component.

    Prevent creation of $validator on every component.

    Versions:

    • VueJs: 2.3.2
    • Vee-Validate: 2.0.0-rc.3

    Description:

    In the beforeCreate() hook of the vee-validate mixin, a $validator object is created for every component in Vue.

    I think this is a bit excessive, and would like to propose that instead it is created only when needed, through a computed property that creates it on the fly on the first use. That way, only the components that use validation need to create this property. In my app, that's maybe about 5% of the used components.

    mixin.js:

    import Validator from './validator';
    
    export default (Vue, options) => ({
      computed: {
        $validator() {
          const validator = new Validator(null, { init: false });
          Vue.util.defineReactive(validator, 'errorBag', validator.errorBag);
          Vue.util.defineReactive(validator, 'fieldBag', validator.fieldBag);
          validator.init();
          return validator;
        },
        [options.errorBagName]: {
          get() {
            return this.$validator.errorBag;
          }
        },
        [options.fieldsBagName]: {
          get() {
            return this.$validator.fieldBag;
          }
        }
      }
    });
    
    

    I haven't tested this yet but am fairly certain that it should work. I am happy to do the testing and create a PR if it's welcome.

    ✨ enhancement 
    opened by lehni 58
  • 📢 Please Read VeeValidate 3.0 docs before creating new issues

    📢 Please Read VeeValidate 3.0 docs before creating new issues

    The new documentation has replaced the old one, These are some links that will help you understand the changes:

    • docs: https://logaretm.github.io/vee-validate/
    • discussion issue: #2191

    The new release introduced breaking changes, I hope everyone has the patience to go through the documentation carefully.

    🗯 discussion 
    opened by logaretm 36
  • vue-test-utils > 1.0.0-beta.12 fails with vee-validate

    vue-test-utils > 1.0.0-beta.12 fails with vee-validate

    Versions:

    • VueJs: 2.5.13
    • Vee-Validate: 2.0.6
    • vue/cli-plugin-unit-jest: 3.0.0-beta.6
    • vue/cli-service: 3.0.0-beta.6
    • vue/test-utils: 1.0.0-beta.10

    Description:

    Hi. I am having some trouble mounting a component which validate a custom component with Jest and Vee-Validate. When I am not unit testing, the components and validations work great. Having those errors when running my test:

    [Vue warn]: Error in config.errorHandler: "TypeError: Cannot set property '_error' of undefined"
    console.error node_modules\vue\dist\vue.runtime.common.js:1739
         RangeError: Maximum call stack size exceeded
    

    (more details at the end)

    Thank you very much in advance for your help.

    Steps To Reproduce:

    Here is the component I am unit testing, Step1.vue :

    <template>
      <div class="step1">
        <test name="POD"  v-model="testData" v-validate="'required'"></test>
        <p v-show="errors.has('POD')" class="is-error">{{ errors.first('POD') }}</p>
      </div>
    </template>
    
    <script>
      import test from "./test.vue"
    
      export default {
        data() {
          return {
            testData: "test"
          }
        },
        components: {
          test
        }
      }
    </script>
    

    Here is the custom component under vee-validation, test.vue :

    <template>
      <div>
        <p>{{currentValue}}</p><button @click="RemoveLetters">Remove letters</button>
      </div>
    </template>
    
    <script>
      export default {
        name: "test",
        props: ["value"],
        data() {
          return {
            currentValue: this.value,
          }
        },
        methods: {
          RemoveLetters: function () {
            this.currentValue = this.currentValue.substring(0, this.currentValue.length -2)
            this.$emit("input", this.currentValue)
          }
        }
      }
    </script>
    

    And here is my Step1.spec.js :

    import { mount, createLocalVue  } from "@vue/test-utils"
    import Component from "./Step1.vue"
    import VeeValidate from 'vee-validate'
    
    let localVue = createLocalVue()
    localVue.use(VeeValidate)
    
    describe("Step1.vue", () => {
      it("renders to a nice snapshot", () => {
        const wrapper = mount(Component, { localVue })
        expect(wrapper.html()).toMatchSnapshot()
      })
    })
    

    Error message:

    PASS  app\components\views\Step1\__tests__\Step1.spec.js
      ● Console
    
        console.error node_modules\vue\dist\vue.runtime.common.js:589
          [Vue warn]: Error in config.errorHandler: "TypeError: Cannot set property '_error' of undefined"
        console.error node_modules\vue\dist\vue.runtime.common.js:1739
          TypeError: Cannot set property '_error' of undefined
              at errorHandler (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\@vue\test-utils\dist\vue-test-utils.js:4446:13)
              at globalHandleError (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:1725:34)
              at handleError (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:1719:3)
              at Array.<anonymous> (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:1837:9)
              at flushCallbacks (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:1756:14)
              at <anonymous>
        console.error node_modules\vue\dist\vue.runtime.common.js:589
          [Vue warn]: Error in nextTick: "RangeError: Maximum call stack size exceeded"
        console.error node_modules\vue\dist\vue.runtime.common.js:1739
          RangeError: Maximum call stack size exceeded
              at Watcher.cleanupDeps (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3183:11)
              at Watcher.get (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3154:10)
              at Watcher.run (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3217:22)
              at Watcher.update (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3205:10)
              at Dep.notify (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:695:13)
              at VueComponent.reactiveSetter [as $attrs] (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:1012:11)
              at updateChildComponent (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:2836:13)
              at prepatch (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:4142:5)
              at patchVnode (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:5923:7)
              at updateChildren (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:5820:9)
              at patchVnode (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:5934:29)
              at VueComponent.patch [as __patch__] (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:6094:9)
              at VueComponent.Vue._update (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:2668:19)
              at VueComponent.updateComponent (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:2786:10)
              at Watcher.get (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3140:25)
              at Watcher.run (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3217:22)
              at Watcher.update (D:\MUST\branches\11.0\SPAs\BookingOneStep\node_modules\vue\dist\vue.runtime.common.js:3205:10)
    
    🙏 help wanted â˜” has workaround 
    opened by SwannLV 35
  • VeeValidate v3.0 🚀

    VeeValidate v3.0 🚀

    VeeValidate 3.0

    This is a draft implementation for version 3.0, which is mostly breaking in many ways but we will try to make it easier to migrate. The changes mostly affect directive usage and will have minimal effects on validation providers.

    This document details all the changes done in v3.

    You can follow the implementation PR here #2153

    You can test the v3 release with the vee-validate-edge npm package.

    Goals

    The goals of this release are as following:

    • Rewrite in TypeScript.
    • v-validate directive deprecation.
    • Overhaul the custom-rules/extension API.
    • Overhaul the localization API.

    TypeScript

    VeeValidate has been TypeScript-friendly for a very long time, but it had its shortcomings. Since it was maintained by contributors - a big shout out to you all - it often wasn't in sync with the actual code. Also, some typings were confusing because they were intended to be internal.

    A TypeScript codebase will not only give us more confidence, but it will also communicate the intent of this library APIs clearly to TypeScript/JavaScript users.

    Some aspects of vee-validate are impossible to Typecheck properly like the injected errors and fields. This is touched upon later.

    Directive Deprecation

    This is the biggest breaking change and will certainly have some backlash against it, the directive, after all, has been the primary way to use vee-validate since x.0 releases. Even vee-validate name is a pun for the v-validate directive.

    But to list the directive problems:

    • Requires global installation, tightly coupled to the rest of the library.
    • Directives do not have props, so to pass stuff around we use data-vv-* attributes which aren't reactive, are repetitive and will add clutter your template.
    • Forces injected state errors and fields to be present.
    • v-if and v-for caveats which aren't apparent to the developer at first glance.
    • Validation Scope is limited within a single component context, it doesn't carry the scope to nested and internal components.
    • Complicated grouping with the Scopes API which is often confused with Validation Scope, also adds clutter to your template.
    • Probably the only library that advertises the use of the Provider/Inject API which is not recommended for public use.
    • Templates can get out of hand and noisy really fast and that makes it harder to debug/maintain.

    Now a little bit of history, why was the directive the default design choice for this library?

    When vee-validate first got released for Vue 1.x the directives was more powerful back then. They had their own props, and they had their own state. Which means the directive was more like a pseudo-component, it was a great choice for this library's API because it did the job perfectly.

    When Vue 2.0 got released, it removed props and this from directives, I believe they were too powerful and a distinction had to be made between them and components, while directives offered a lower level access to the DOM it meant that they had to do less, yet I was stubborn and the API was left as is. I needed to implement external state management and resort to data-vv-* attributes. It wasn't very clean but it did the job again so the API remained the same, and because we had no better way of doing template based validation, it was fine.

    Then scoped-slots came out, and it took a while for me to properly understand how they can be used to run validation, remember what I said about directives? well, components while "high-level", they offer "low-level" access to Vue's virtual DOM. Which is what I needed exactly and what was missing for the directive.

    Now I'm going to talk about the biggest problems with the directive.

    Injected State

    The need for the injected state is caused by directives being stateless, as they don't have this and no longer can store stuff on their own. This change was introduced in Vue 2.0 release which was the biggest limitation introduced to directives.

    The primary way to use v-validate directive is to get your errors off an injected global state called errors, this causes a problem for maintenance sake as it is not immediately clear where did errors come from, which is the same downsides for using global mixins. Your teammates simply had to know that the project is using vee-validate.

    Being a globally present state, it has poor performance as it changes frequently depending on how many fields are reading/writing to that state. This can be observed if you have 100+ fields on the same page, which while is very rare it still meant that by default vee-validate wasn't performant.

    they are impossible to type check properly without breaking somebody's code out there.

    That leaves us with one option: Use mapState like a helper to explicitly inject state, very much like vuex. I originally intended for the directive to be in v3 and introduced a full-rewrite that implements that. But the API was unwieldy in my opinion and it didn't solve the performance issue, in fact, it made it worse.

    v-if and v-for caveats

    The directive life-cycle methods work most of the time, but when Vue decides to re-use a field to save up rendering time, The directive doesn't get notified in any way. Meaning if the directive was to pick up changes in the template it had to re-check the field it is being attached to every single time before validation, which degrades performance even further as observed in the test implementation I talked about earlier.

    Directives weren't meant to be dependent on the identity of the element they are being attached to, they should be dependent solely the expression and the directive args/modifiers configured for it. Which is what was missing for my initial understanding of directives.

    Sharing state between components

    Using inject API for sharing state between a parent component and a child component being validated wasn't very intuitive, also the confirmed rule and any cross-field rule would never work across components as they rely on the refs present in the context of the v-validate usage.

    This problem comes up weekly, and while we could argue the docs can do a better job to describe this issue, I think by trying to address many caveats it means that the API isn't that good in the first place.

    Scope API

    the data-vv-scope API was just ugly, confusing and was redundant most of the time. I personally never used it, and my team at Baianat rarely did and it rarely comes up in issues, which is an indication that it is underused, that means developers did not have multiple forms in the same component that often.

    Aside from looks, it also had a hand in performance degradation, because while maybe.field can be a name for a field called literally "maybe.field" or it could be a field scoped within a "maybe" scope name. That means that every time errors.first and errors.has are used, a lot of computation has to be done to determine which case is it. Another smell for bad API.

    And since directives do not have access to the rendering phase, it meant that they had no way to prepare some stuff beforehand. For example, to access field flags you need to always check for the field existence first:

    fields.name && fields.name.valid
    

    Which is annoying in large forms but there is no way around that, I tried playing around with Proxies, but they cannot be poly-filled and messed up big time with Vue.js dev-tools.

    The validator API was a mess

    There were actually two validator classes present, one injected in each component and the other would be the one you normally import from vee-validate and the two had identical public API but it was a mess. for example, validate and validateAll did the exact same thing. validateScopes was just an added confusion, another smell for a bad API.

    The alternative

    One of the goals of this release is to promote better practices, that meant less magic. So the directive had to go since it inherently promoted a few practices that are considered evil. You have been probably using vee-validate for your production site and it certainly did the job well, but did it feel elegant? There are two ways to make a simple API, it can be simple but crude or it can be simple as in elegant. I strive for the latter and I'm sure we all do.

    For the last few months, I have been advertising the use of ValidationProvider and ValidationObserver components recently whenever anyone faces one of the above problems. They will be the primary way to use v-validate as of the time of this writing. The other way that can be introduced in the future if Vue.js adds new APIs to be built upon like the function API if it made sense.

    At first, glance, using the ValidationProvider is more verbose, but when refactored properly they are much more productive and flexible than the directive. Also, the component API is very powerful and can allow some "magic" to happen. For example, the ValidationObserver can pick up ValidationProvider instances no matter how deeply nested they are and even if they are being used internally by other components. That means the Observer is able to correctly represent the state of forms.

    Since Observers can be nested, that solved the problem of scoping, as you can group fields together by observers and it is much more cleaner and clearer in the template than the old data-vv-scope API.

    They are superior in every way to the directive and having two APIs means the documentation would be splintered and one would have focused over the other, so the components API survived for being the better one.

    VeeValidate Global API

    VeeValidate has been re-written to expose a function-based API, this isn't a coincidence with the recent events in Vue.js community, it had been planned for a while.

    In short, The Validator, ErrorBag classes have been deprecated as they no longer were needed in favor of a new stateless API. So v3 exposes the following functions:

    • extend
    • localize
    • validate
    • configure
    • setInteractionMode
    • ValidationProvider
    • ValidationObserver
    • withValidation

    All of which are tree-shakable and more friendly to your bundle size.

    validate API

    Used to be the verify API, It is stateless, unlike the old Validator class, with this function you can run arbitrary validation for values using the vee-validate rule system and asynchronous validation pipeline with an i18n support without having to integrate components or anything in your project. Heck, you could even use it server-side, or if you are feeling a little rebellious you can use it inside other validation libraries like vuelidate.

    Common Uses for this are:

    • Vuex: as you might want to validate values in actions before committing them to the state.
    • Validating values rather than fields, which will come in handy if a certain Vue RFC is implemented 😉.

    extend API

    Used to be the Validator.extend method.

    There are a few problems with the current rule system, especially for Date/Cross-field rules:

    • Date Validation is clunky and is dependent on date-fns implementation which lacks proper timezone support.
    • Fields can only target one field at a time which makes it impossible to cross-field-check multiple fields.
    • Value transformation/normalization before validation is usually needed, but is redundant if implemented as part of the rule.
    • Unnecessary increase to the footprint of vee-validate as date rules are rarely used, compared to required.
    • Impossible to pass objects reliably as rule parameters instead of an array.

    To fix this, date rules were deprecated, it is up to you to implement those rules and the new API will make it much easier. You can also use any JS date library you want, date-fns, moment, dayjs to name a few options.

    The value transformation/casting API allows you to prepare the value/params before validating. This plays nicely with cross-field validation, which will only transform a field vid to its value, this will be one of the few transformations available out of the box and will not be configurable.

    This is also handy when you want your field to emit a value of certain structure but want the custom validator to validate a certain aspect of that structure, for example you want to pass { value: 'xyz', id: 5 } to your model but you only want to validate the value prop.

    The proposed API looks like this:

    Validator.extend('rule', {
      validate (value, params) {
        // validate method, required if its a new rule, optional if already exists.
      },
      message (fieldName) {
        // message, optional.
      },
      params: [
        { name: 'paramName', isTarget: true }, // applies a locator transform to get the other field value.
        {
          name: 'otherParam',
          cast (value) {
            return new Date(value); // cast the param value before using it.
          }
        },
        // this param uses both transforms to locate the other field, then transforms its value.
        {
          name: 'complex',
          isTarget: true,
          cast (value) {
            return 'whatever'; // Cast the other field value
          }
        },
        immediate: false, // this rule should not trigger when the field is initially validated.
        computesRequired: false, // this rule can change the required state of this field.
      ]
    })
    

    Note that the isTarget prop on the rule itself has been deprecated.

    This is rather complex but it will be only used in complex rules. So it won't be used often. Also, it solves the object vs string param formatting, since in the string case it would be necessary to know the order of the params, but in objects, it is necessary to know the names of the params. when you provide a params array, it will always be passed as an object to your rule.

    It isn't required tho, you can still ignore the params array entirely and the params will be passed as-is to your rule, if you provide an object it will be passed as an object, same for the string syntax.

    Here is a snippet on how you would implement the after rule:

    import { extend } from 'vee-validate';
    import { parse, format, isValid, isAfter } from 'date-fns';
    
    extend('after', {
      validate (value, { other }) {
         const parsed = parse(value, 'some-date-format');
         if (!isValid(parsed)) return false;
    
         return isAfter(value, other);
      },
      // parse the field value.
      castValue: value => parse(targetValue, 'some-date-format', new Date(),
      params: [
        {
          name: 'other',
          isTarget: true,
          cast (targetValue) {
            // parse the target field value.
            return parse(targetValue, 'some-date-format', new Date());
          }
        }
      ]
    });
    

    Now its always guaranteed that other will be a date value and since you are parsing the value yourself in the validate function. It is very straightforward to implement complex rules like these.

    The extend function options are entirely optional. You can progressively extend and add more options or modify them in your rules during the life-cycle of your application.

    import { extend } from 'vee-validate';
    
    // A simpler shorthand for passing params.
    extend('ruleFn', {
      params: ['first', 'second'],
      // ... other stuff
    });
    
    // New rule without options and passing a validate function directly.
    extend('ruleFn', () => {
      return false;
    });
    
    
    // Add/Modify configuration for the rule.
    extend('ruleFn', {
      // options..
    });
    

    A11y

    VeeValidate offered basic accessibility features in v2 and in v3 it will go a step further.

    ariaInput

    The ValidationProvider slot props expose an ariaInput object which you can bind to your inputs:

    <template>
      <ValidationProvider rules="required" v-slot="{ aria }">
        <input type="text" v-model="value" v-bind="aria" />
        <pre>{{ aria }}</pre>
      </ValidationProvider>
    </template>
    
    <style>
    input.invalid {
      border: solid 1px red;
    }
    
    input.valid {
      border: solid 1px green;
    }
    </style>
    

    ariaMsg

    ariaMsg is another set of aria attributes, but you bind it to your error display element. A full example would look like this:

    <ValidationProvider rules="required" v-slot="{ errors, ariaInput, ariaMsg }">
      <div>
        <input type="text" v-model="values.classes" v-bind="ariaInput">
        <pre>{{ ariaInput }}</pre>
        <span v-bind="ariaMsg">{{ errors[0] }}</span>
      </div>
    </ValidationProvider>
    

    localize API and i18n

    The dictionary-based implementation for VeeValidate has been confusing to some, and in the Vue ecosystem, it was not widely used directly. For example, people opted often to use VueI18n since maintaining two validation APIs was problematic, it meant vee-validate had to provide its own adapter for VueI18n which is unnecessary kilobytes in the wire for those who use non-Node.js solutions for their SSR like PHP's Laravel.

    The new API has to be generic, it means the old dictionary had to be hidden away and used behind the scenes. It also means users should be able to have a way to use any i18n library they like.

    The localize function is an abstraction for the included simple dictionary, and its signature is identical to the Validator.localize method of the old API.

    import { localize } from 'vee-validate';
    
    localize('ar', {
      messages: {
        required: 'هذا الحقل مطلوب'
      }
    });
    

    The full dictionary looks like this:

    localize({
      en: {
        fields: {
          // custom messages for each field.
        },
        messages: {
          // messages for each rule.
        },
        names: {
          // custom field names.
        }
      }
    });
    

    Note that by default vee-validate does not install any locale or rules, you have to import what you need or opt-in to use the full build which has messages and rules loaded beforehand. but with extra footprint cost.

    The localize method is only useful if you plan to use the internal i18n dictionary used by vee-validate. But if you want to run your own solution like VueI18n you could do so while installing rules:

    import { extend } from 'vee-validate';
    import VueI18n from 'vue-i18n';
    import { required } from 'vee-validate/dist/rules';
    
    const i18n = new VueI18n({
      locale: 'en',
      messages: {
        en: {
          validation: {
            required: 'This field is required'
          }
        }
      }
    });
    
    extend('required', {
      ...required, // rule definition
      message (field, values) {
        return i8n.t('validation.required');
      }
    });
    

    Not importing the localize function will drop it from the bundle because its tree-shakable, and will reduce your bundle size down further.

    For convenience, vee-validate messages format was updated to be VueI18n compliant, for example:

    {
      max: `The {_field_} may not be greater than {length} characters.`,
      max_value: `The {_field_} must be {max} or less.`,
      mimes: `The {_field_} must have a valid file type.`,
      min: `The {_field_} must be at least {length} characters.`,
      min_value: `The {_field_} must be {min} or more.`
    }
    

    With that being said, the message generator signature was changed to look like this:

    interface ValidationMessageGenerator {
      (field: string, values: { [k: string]: any }): string;
    }
    

    Which means params and data are now merged into the same object. A message now can be either a templated message like shown above or a function that returns a string. That means you can use any i18n implementation out there.

    Bundle-size

    Few rules were removed due to their size and they are very easy to implement:

    • url
    • ip
    • ip_or_fqn
    • credit_card
    • date_format
    • after
    • before
    • date_between
    • decimal (often confused with integer and digits)

    This means vee-validate no longer depends on validator.js and will allow you to use whatever version of validator.js to add the rules you need without conflicts from vee-validate internal copy of it.

    Some rules behavior has been changed:

    The email rule implementation was changed to a simpler regex pattern check, so it might be less accurate than v2 releases.

    The length rule will only check if the given string/iterable length matches a specific length that is provided, it will no longer allow max param to be passed.

    The rules represent about 4kb on their own, they will be excluded by default and you will need to import the rules your app will be using. There is a full bundle with all the rules pre-configured. This allows us to add more rules in the future without worrying about the bundle size as it has been the case with 2.x releases.

    The bundle size of vee-validate v3 has dropped significantly:

    | Default Bundle | 2.x size | 3.0-alpha size | |--------------------------|----------|----------------| | Disk | 136kb | 79kb | | Minified | 58.7kb | 21kb | | Minified + Gzipped | 16kb | 13kb |


    | Full Bundle | 2.x size | 3.0-alpha size | |--------------------|----------|----------------| | Disk | 350kb | 84kb | | Minified | 124kb | 32kb | | Minified + Gzipped | 31kb | 17kb |

    This means vee-validate is no longer costly and still offers many of the features that made it popular.

    About v2

    VeeValidate 2.x will still be maintained and checked for bugs, all critical issues will be fixed in a timely manner, but will receive slower updates for newer stuff.

    Migration

    There will be a migration guide detailing the changes and how to replace each feature with its new implementation.

    You can follow the progress here: #2153

    🌟 feature ðŸ—¯ discussion ðŸ’£ breaking 
    opened by logaretm 34
  • Once an input has been visible using v-if, it always validates it as part of the form even when hidden again.

    Once an input has been visible using v-if, it always validates it as part of the form even when hidden again.

    Versions:

    • VueJs: 2.0.3
    • Vee-Validate: beta17

    Description:

    Hi,

    I'll publish a jsfiddle if required, but perhaps you're already aware of this issue. I have form in which I have some items that I do not want to display using v-if tags.

    If the input has been shown once, and then has been hidden using v-if = false then it seems that vee-validate is still validating the hidden field. It work great as long as the input has been hidden from the page load, but once displayed, and hidden again, it continues validating it.

    Is this a known issue?

    Steps To Reproduce:

    opened by denjaland 31
  • Can't validate form with multiple child components

    Can't validate form with multiple child components

    Hi,

    In our app we have some fairly complex dynamic forms that have been broken down into multiple sub components and can be nested a few levels deep. We also currently using vuex too.

    I don't seem to be able to get all the components to validate when validateAll is called at the parent level. After having a look at the source code it looks like this only emits and listens on the same component.

    Is this something that we should currently be able to do or something that might be looked at in the future?

    Regards James

    opened by sproogen 29
  • [Vue warn]: Error in directive validate bind hook:

    [Vue warn]: Error in directive validate bind hook: "TypeError: Cannot read property '$scopedSlots' of undefined"

    Essentially, I'm just mounting a component that has children with v-validate prop on a test.

    Once I remove the v-validate prop from the children, the test passes just fine.

    Any idea why that happens?

    Edit:

    Reproducing is possible here: https://github.com/jourdanrodrigues/v-validate-issue. I'm having this issue on a MacOS Mohave and Ubuntu/Alpine (Docker) and VeeValidate 2.2.x.

    🤔 needs reproduction 
    opened by jourdanrodrigues 28
  • Validating a non-existent field:

    Validating a non-existent field: "result". Use "attach()" first.

    Versions

    • vee-validate: 2.1.6
    • vue: 2.5.2

    Describe the bug So I am getting this error on my system "Uncaught (in promise) Error: [vee-validate] Validating a non-existent field: "result". Use "attach()" first." I don't know why I get this error. Also I am not getting this error for every field I use this.$validator.validate() on but only in the last step

    To reproduce Created this fiddle https://jsfiddle.net/f1uk3r/bnrpdg01/1/

    Expected behavior The error should not come and it should log "passed when clicked submit."

    🐛 bug 
    opened by f1uk3r 27
  • Clear errors after form submition

    Clear errors after form submition

    Versions:

    • VueJs: 2.1.7
    • Vee-Validate: 2.0.0-beta.18

    Description:

    Once I submit the form I clear the fields and I want to clear the errors as well, but I'm having a hard time trying to do that.

    Steps To Reproduce:

    Form:

    <form role="form" class="form-horizontal" @submit.prevent="persistData">
                <legend>Supervisor & Deputy Requests</legend>
    
                <div class="form-group">
                    <label for="requesttype" class="col-sm-2 control-label">Request type</label>
                    <div class="col-sm-10">
                        <select v-model="form.requesttype" name="form.requesttype" id="requesttype" class="form-control"
                                data-vv-rules="required" v-validate.initial="form.requesttype">
                            <option value=""></option>
                            <option value="Option 01">Option 01</option>
                            <option value="Option 02">Option 02</option>
                        </select>
                        <span v-show="errors.has('form.requesttype')" class="text-danger">This field is required</span>
                    </div>
                </div>
                <div class="form-group">
                    <label for="userid" class="col-sm-2 control-label">User ID</label>
                    <div class="col-sm-10">
                        <input v-model="form.userid" name="form.userid" type="text" class="form-control" id="userid"
                               data-vv-rules="required"
                               v-validate.initial="form.userid">
                        <span v-show="errors.has('form.userid')" class="text-danger">This field is required</span>
                    </div>
                </div>
                <div class="form-group">
                    <label for="requestdescription" class="col-sm-2 control-label">Request description</label>
                    <div class="col-sm-10">
                        <textarea v-model="form.requestdescription" name="form.requestdescription" class="form-control"
                                  id="requestdescription" cols="30"
                                  rows="10" data-vv-rules="required"
                                  v-validate.initial="form.requestdescription"></textarea>
                        <span v-show="errors.has('form.requestdescription')"
                              class="text-danger">This field is required</span>
                    </div>
                </div>
    
                <button type="submit" class="btn btn-primary pull-right">Submit</button>
            </form>
    

    Persist data method:

                    let self = this
                    // Validate All returns a promise and provides the validation result.
                    this.$validator.validateAll().then(success => {
                        if (!success) {
                            // handle error
                            console.log('Error!')
                            return
                        }
                        axios.post('/static/api/SupervisorDeputyRequest/persistdata.php', queryString.stringify(self.form))
                            .then(res => {
                                self.form = {
                                    requesttype: '',
                                    userid: '',
                                    requestdescription: ''
                                }
                            })
    

    I want to clear the errors in the AJAX callback. This code is in a .vue file and vee-validate is being imported in the main.js file.

    opened by badcom 27
  • Validate doesn't work in v-for

    Validate doesn't work in v-for

    Versions:

    • VueJs: 2.1.10
    • Vee-Validate: 2.0.0-beta.22

    Description:

    v-validate doesn't work on 2.0.0-beta.22

    Steps To Reproduce:

    I prepared https://jsfiddle.net/hf96yxxy/4/ using 2.0.0-beta.22, when the Name is empty, shows no errors. It does show error on 2.0.0-beta.21, but it cannot parse the index

    🐛 bug duplicate 
    opened by murpzhu 24
  • "Unexpected token export" when importing validation rules with Jest

    Versions

    • vee-validate: 3.0.4
    • vue: 2.6.10

    Describe the bug I've seen that this issue has already been opened for Nuxt (#2282, #2249, #2240) and that the solution in that case is documented. But I encounter it in a vue-cli app, using TS and Jest, and I struggled to make it work.

    To reproduce Steps to reproduce the behavior:

    1. create a CLI app with TS and Jest
    npx @vue/cli create vee-v3 -m npm --inlinePreset '{"useConfigFiles": true,"plugins": {"@vue/cli-plugin-typescript": {"classComponent": false},"@vue/cli-plugin-unit-jest": {}}}'
    
    1. install vee-validate
    npm install vee-validate --save
    
    1. add vee-validate/dist/rules to HelloWorld.vue
    import { extend } from 'vee-validate';
    import { required } from 'vee-validate/dist/rules';
    extend('required', required);
    
    1. run the unit tests
    npm run test:unit 
    

    throws:

    export { alpha$1 as alpha, alpha_dash, alpha_num, alpha_spaces, between, confirmed, digits, dimensions, email, excluded, ext, image, integer, is, is_not, length, max, max_value, mimes, min, min_value, numeric, oneOf, regex, required, required_if, size };
        ^^^^^^
    
        SyntaxError: Unexpected token export
    

    I tried to tweak jest.config.js but I'm still running into the issue... I tried several approches from https://github.com/facebook/jest/issues/2550 without success.

    Do you have a working configuration for this use-case? If so, it would be great to add it to the documentation.

    (But TBH it would be better to change the rules.js packaging to make the issue go away, and avoid contorsions with build/testing tools)

    ✨ enhancement 
    opened by cexbrayat 23
  • Schema and rules at the same time

    Schema and rules at the same time

    While testing out VeeValidate, I found out I was unable to use both a schema and per-field-assigned rules, which surprised me. If schema is set on the form, the rules are ignored.

    In other words, adding a schema to a form effectively disables all existing validation.

      <Form @submit="submitHandler" :validation-schema="schema">
    
        <label class="block mb-4">
          {{ $t('Last name') }}
          <Field name="surname" type="text" :rules="requiredString"/>
          <ErrorMessage name="surname"/>
        </label>
    ...
    

    This comes for practical reasons - sometimes there are dynamic fields and it's easier to just write that one special rule outside of the schema.

    This is not a dealbreaker for me, it just surprised me that the field-assigned rules simply stop working. I'd suggest to at least adding a warning. Ideally, the rules would be preserved.

    [Vue v3, VeeValidate v4.x]

    opened by dakujem 0
  • Extra fields errors

    Extra fields errors

    I'm using a strict server validation and what happens is on extra field, there is no visual feedback and to process the error is very laborous.

    Example setup:

    1. the form has fields anomaly, boom, cone,
    2. the server only accepts boom and cone
    3. the submission error handler is similar to this:
      errorsFromServer.forEach(
        (v) => actions.setFieldError(v.source, v.message)
      )
      

    The problem is that the v.source is equal to anomaly and thus the error message ("Extra field anomaly present in the request.") is NOT shown anywhere.

    The ideal solution would be the ability to set a callback that would process the unprocessed errors.
    I don't have enough knowledge to say how that fits with VeeValidate, unfortunatelly. I'd assume the setter (and potentially the getter too) would be part of the actions object, something like actions.setUnprocessedErrorHandler(myHandlerForUnprocessedErrors).
    I reported the same issue with Formkit and it was one of 3 reasons why we're considering moving away from Formkit, and here I am testing VeeValidate, to be honest.

    Of course I understand that a userland solution would be to check for the unprocessed error messages (extra fields) manually, but for nested forms with repeating parts this becomes extremly tedious and the support on the library side would help considerably.

    [Vue v3, VeeValidate v4.x]

    opened by dakujem 0
  • [v4] to setValues an array type not work

    [v4] to setValues an array type not work

    What happened?

    please, help me!! thats a strange question

    ===> Working:

    image

    <template>
      <div>
        <q-form
          @submit="formSubmitEvtFn"
          class="q-gutter-y-md q-mt-md"
          ref="formRef"
        >
          <div
            v-for="(contact, idx) in fields"
            :key="contact.key"
            class="row no-wrap"
          >
            <div class="col-4">
              <Field :name="`contacts[${idx}].name`" v-slot="{ field }">
                <q-input
                  :model-value="(field.value as string)"
                  v-bind="field"
                  :error-message="(formErrors as any)[`contacts[${idx}].name`]"
                  :error="!!(formErrors as any)[`contacts[${idx}].name`]"
                  type="text"
                  label="Contact Name"
                  outlined
                />
              </Field>
            </div>
          </div>
        </q-form>
      </div>
    </template>
    
    <script setup lang="ts">
    import { ref, onMounted } from 'vue';
    import { QForm } from 'quasar';
    import { object, string, array } from 'yup';
    import { useForm, useFieldArray, Field } from 'vee-validate';
    
    import { MyAPI } from '@/apis/user';
    
    onMounted(async () => {
      try {
        const res = await MyAPI();
    
        // ================ Doesn't Working =========================
        console.log('res contacts FROM API ===> ', res.contacts);
    
        // ================ Working =========================
        // res.contacts = [
        //   {
        //     name: 'manual name',
        //     phone: 'manual phone',
        //   },
        // ];
        // console.log('res contacts Customly ===> ', res.contacts);
    
        setValues({
          contacts: res.contacts,
        });
      } catch (e) {}
    });
    
    const formSchema = object().shape({
      contacts: array().of(
        object().shape({
          name: string().required().label('Contact Name'),
          phone: string().required().label('Contact Phone'),
        })
      ),
    });
    
    const {
      handleSubmit: formVeeSubmitFn,
      errors: formErrors,
      setValues,
    } = useForm<{
      contacts: any;
    }>({
      validationSchema: formSchema,
    });
    
    const formRef = ref<QForm>();
    const { fields } = useFieldArray('contacts');
    
    // Click Save and verify fields
    const formSubmitEvtFn = formVeeSubmitFn(() => {
      console.log('formSubmitEvtFn...');
    });
    </script>
    
    

    Reproduction steps

    1. It doesn't working when using res.contacts from API, i get an error image
    2. it does working when i manual setting it
    res.contacts = [
    {
        name: 'name111',
        phone: 'phone1',
      },
    ];
    

    Version

    Vue.js 3.x and vee-validate 4.x

    What browsers are you seeing the problem on?

    • [ ] Firefox
    • [ ] Chrome
    • [ ] Safari
    • [X] Microsoft Edge

    Relevant log output

    No response

    Demo link

    not have...

    Code of Conduct

    🤔 needs reproduction 
    opened by wonderfate 2
  • Access the `Form`s `values` from a `ref`

    Access the `Form`s `values` from a `ref`

    For some reason, I was trying to set the validation-schema dynamically based on the inputs new values, I needed to access the Form values through a ref and I was expecting to find the current form values but I didn't found it. It would be nice to have this in the Form instance.

    image

    ✨ enhancement request 
    opened by BudiSalah 2
  • Values from `handleForm` are cast or are taken off of input and not model?

    Values from `handleForm` are cast or are taken off of input and not model?

    What happened?

    I am trying to do validation for date input and on the model I get the date object as I should, but when I submit the form and I log the values I get that field value cast to string.

    I want to preserve the dates as instanceof Date and I'm not sure if it does the same thing to numbers, but I'd like number to remain the number.

    I spent hours trying to figure our what is wrong. Thought at first that maybe Yup is casting the value after validation to a string, but that does not seem to be the case.

    So now I am unsure if it's handleForm that does it or useField that I have on my component.

    Please clarify to me and let me know if there's anything I can do to retain the type.

    Reproduction steps

    No response

    Version

    Vue.js 3.x and vee-validate 4.x

    What browsers are you seeing the problem on?

    • [X] Firefox
    • [X] Chrome
    • [X] Safari
    • [X] Microsoft Edge

    Relevant log output

    `handleForm values:  {date: '11/15/2022'}`
    `date model value: Tue Nov 15 2022 10:31:23 GMT+0100 (Central European Standard Time)`
    

    Demo link

    n/a

    Code of Conduct

    🤔 needs reproduction 
    opened by nenadnovakovic-sh 1
  • Support for warning array and success array

    Support for warning array and success array

    Is your feature request related to a problem? Please describe.

    Currently vee-validate library only supports displaying error messages using component, in future it might become a necessasity to support multiple warning message using a component, which will have a presedence after an errormesssage

    display order Error > Warning > Success Message

    Similarly there should be a component to display array of success messages.

    Describe alternatives you've considered

    Formik supports all the three although they don't have a specific component from them, there is a doc for developers to follow and know how to create these to seperate component using the same metheds.

    ✨ enhancement request 
    opened by arindampradhan 0
Releases(v4.7.3)
  • v4.7.3(Nov 13, 2022)

  • v4.7.2(Nov 2, 2022)

  • v4.7.1(Oct 23, 2022)

  • v4.7.0(Oct 9, 2022)

    🆕 New Features

    Controlled values filtering #3924

    A good use-case is where you assign a bunch of values as initial values to your form but your inputs only control a few of them but it wasn't possible to extract these controlled values from all the values.

    v4.7 Lets you do that using a few ways:

    You can grab controlledValues from useForm result

    const { handleSubmit, controlledValues } = useForm();
    
    const onSubmit = handleSubmit(async () => {
      // Send only controlled values to the API
      // Only fields declared with `useField` or `useFieldModel` will be sent
      const response = await client.post('/users/', controlledValues.value);
    });
    

    Or use withControlled composed function:

    const { handleSubmit } = useForm();
    
    const onSubmit = handleSubmit.withControlled(async values => {
      // Send only controlled values to the API
      // Only fields declared with `useField` or `useFieldModel` will be sent
      const response = await client.post('/users/', values);
    });
    

    vee-validate marks fields which were created using useFieldModel or useField (and <Field />) as "controlled" and these would be the only values included in the previous samples.

    Explict form context option #3204

    Previously useField and <Field /> components used implicit injections to resolve the form context they are part of. This prevented having multiple form contexts within the same component with useForm since each call will take over the fields declared after.

    Now when declaring fields with useField you can pass form option explicitly to assign that field to that form:

    const form1 = useForm();
    const form2 = useForm();
            
    const field1 = useField('field', undefined, {
      form: form1,
    });
    
    const ield2 = useField('field', undefined, {
      form: form2,
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v4.6.10(Sep 30, 2022)

    🐛 Bug Fixes

    • Fixed using File constructor while in SSR (56663aa2e50d7aa285ca1cb22887c8e8b3f7fd3c)

    i18n 🌍

    • Updated SK and CS language files to include missing rules thanks to @Liwoj #3936 #3937
    Source code(tar.gz)
    Source code(zip)
  • v4.6.9(Sep 19, 2022)

    🐛 Bug Fix

    • Fixed an issue where resetForm would leave behind null or undefined in array fields after reset #3934 (1c016d93b367229644dca643931ef63bc6e433dc)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.8(Sep 19, 2022)

    🐛 Bug Fixes

    • Run validation if we skip checkbox value setting if event trigger should validate #3927 (#3930)
    • Fix File value instance equality checks #3911 (#3932)
    • Fix nested value change not triggering validation when validateOnValueUpdate is enabled #3926 (#3929)

    👕 TypeScript

    • Exposed RuleExpression type #3913 (cdaf22df04b42a68f55133ad3854aae9a7ad6953)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.7(Aug 27, 2022)

    👕 TypeScript

    Allow generics types to be passed to GenericValidatorFunction which previously caused errors with simple snippets like this:

    function validator(value: string) {
      // ...
    }
    
    const { value } = useField('field', validator);
    

    🐛 Bug Fixes

    • Fixed an issue with async function validators not respecting the last run error messages #3906 (#3908)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.6(Aug 16, 2022)

  • v4.6.5(Aug 11, 2022)

    🐛 Bug Fixes

    • Fixed an issue where checkboxes bound to an object could fail unchecking #3883 (#3885)
    • Fixed an issue with field's meta.dirty not being set correctly after calling resetField with a new value #3891 (#3892)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.4(Aug 7, 2022)

    🐛 Bug Fixes

    • Fixed an issue where useFieldModel did not trigger validation for nested paths (fbe273c6f2c5d30a1996777561eda2268d8a02e0)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.3(Aug 7, 2022)

  • v4.6.2(Jul 17, 2022)

    👕 TypeScript

    • Expose FieldOptions and FormOptions interfaces #3843 (7437612ab554f8f65b445f7b065725b570a9a14a)

    🐛 Bug Fixes

    • Avoid toggling field array checkboxes values when an item is removed #3844 (fffad4bea68cc949d0bce440b5daf43901aaca7f)
    Source code(tar.gz)
    Source code(zip)
  • v4.6.1(Jul 17, 2022)

  • v4.6.0(Jul 12, 2022)

    This release has been in the making for a while and I'm really glad it is finally released with a lot of requested improvements and new features.

    🆕 New Features

    v-model with FieldArray API

    You can now use v-model directive with any kind of input to mutate the field array value directly without having to use <Field /> or useField.

    <Form>
      <FieldArray name="users" v-slot="{ fields }">
        <div v-for="(field, idx) in fields" :key="field.key">
          <input v-model="fields[idx].value" />
        </div>
      </FieldArray>
      
      <button>Submit</button>
    </Form>
    

    Keep values after fields are unmounted

    By default, vee-validate destroys the form values automatically whenever a field is unmounted. This made creating tabbed forms or multi-step forms a little bit harder to achieve since you needed to implement a mechanism to track the values independently from vee-validate.

    Now there is a new (config available) (e6e1c1d) that allows you to control this behavior on the form and field levels.

    In the component API, you can pass keepValue or keepValues to <Field /> and <Form /> components respectively.

    <!-- Now all field will keep their values when unmounted unless specified otherwise -->
    <Form keep-values>
      <template v-if="showFields">
        <Field name="field" as="input" rules="required" />
        <!-- This field opts out and its value will be destroyed -->
        <Field name="[non-nested.field]" :keep-value="false" />
        <Field name="drink" as="input" type="checkbox" value="Tea" rules="required" /> Tea
      </template>
    
      <button>Submit</button>
    </Form>
    

    You can also pass keepValueOnUnmount and keepValuesOnUnmount to useField() and useForm() respectively:

    useForm({
     // default is false
      keepValuesOnUnmount: true
    });
    
    useField('field', undefined, {
      // default is whatever the form is configured to, if no form then `false`
      keepValueOnUnmount: true
    });
    

    Note Keep in mind that the field config takes priority over the form config if specified. Otherwise, all fields will follow the form's config.

    useFieldModel API

    A new useFieldModel function was added] to useForm which introduces a new way to use useForm without having to call useField.

    The reason for this is useField is meant to create input components, not model bindings. The useFieldModel allows you to create bindable refs that you can use directly with v-model on your components or any 3rd party components. This makes it significantly easier to integrate with 3rd party libraries.

    <template>
      <input name="email" v-model="email" />
      <span>{{ errors.email }}</span>
    
      <input name="password" v-model="password" type="password" />
      <span>{{ errors.password }}</span>
    </template>
    
    <script setup>
    import { useForm } from 'vee-validate';
    import MyTextInput from '@/components/MyTextInput.vue';
    
    // Define a validation schema
    const simpleSchema = {
      email(value) {
        // validate email value and return messages...
      },
      name(value) {
        // validate name value and return messages...
      },
    };
    
    // Create a form context with the validation schema
    const { errors, useFieldModel } = useForm({
      validationSchema: simpleSchema,
    });
    
    const email = useFieldModel('email');
    const password = useFieldModel('password');
    
    // or multiple models at once
    const [email, password] = useFieldModel(['email', 'password']);
    </script>
    

    This is much less verbose than useField and is optimized to be just a validatable model. However you will no longer have access to the advanced state and capabilities of useField like meta and validation triggers. So you will need to implement your own logic for when to show errors as they will be generated immediately whenever the value changes.

    Automatic v-model events with useField

    Quite often you will setup your component to support v-model directive by adding a modelValue prop and emitting a update:modelValue event whenever the value changes.

    If you use useField in your input component you don't have to manage that yourself, it is automatically done for you. Whenever the useField value changes it will emit the update:modelValue event and whenever the modelValue prop changes the useField value will be synced and validated automatically.

    The only requirement is you need to define your model prop on your component explicitly.

    <script setup>
    import { useField } from 'vee-validate';
    
    defineProps({
      // Must be defined
      modelValue: {
        type: String,
        default: '',
      },
    });
    
    const { value } = useField('field', undefined);
    </script>
    

    You can change the default model prop name by passing modelPropName option to useField:

    <script setup>
    import { useField } from 'vee-validate';
    
    defineProps({
      // Must be defined
      custom: {
        type: String,
        default: '',
      },
    });
    
    // component will now emit `update:custom` and sync `custom` prop value with the `value` returned from `useField`.
    const { value } = useField('field', undefined, {
      modelPropName: 'custom',
    });
    </script>
    

    You can also disable this behavior completely and manage those events yourself by passing syncVModel option to useField:

    <script setup>
    import { useField } from 'vee-validate';
    
    // Now it won't emit anything and won't sync anything
    const { value } = useField('field', undefined, {
      syncVModel: false,
    });
    </script>
    

    Other minor new features

    • Added move() to FieldArray (a52f133)
    • If you are using a native <input type="file"> element its value will now respect the multiple attribute, if it is present and set to true then it will be an array of files. Otherwise, it will be a single file. This could be a breaking change for some.

    👕 TypeScript Changes

    • Expose ValidationOptions type #3825 (9854865)
    • Exposed component APIs to their TS defs with refs #3292 (ae59d0f)
    • Remove yup type dependency (#3704) (e772f9a). This sadly loses the ability to infer the types from a yup schema, however it caused more errors than it is worth and introduced an installation dependency on yup even if it is not used.

    🐛 Bug Fixes

    • Use multiple batch queues for both validation modes #3783 (6156603)
    • Compare form's meta.dirty based on original values than staged initials #3782 (f3ffd3c)
    • Avoid value binding for file type inputs #3760 (3c76bb2)
    • Added existing undefined path fallback for optional arrays #3801 (fd0500c)
    • Added argument order for digits rule inja.json#3780 (9385457)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.11(Apr 10, 2022)

    🐛 Bug Fixes

    • Ignored validation of fields during unmounting #3748 (3d49faa4101902c2e77aee0a2d43cd29b69f7b4e)

    🆕 New Features

    useField now allows the usage of array of functions instead of a single function to perform validation (https://github.com/logaretm/vee-validate/issues/3725) #3726 thanks to @gbaquedano

    const {
      value: value,
      errors: errors,
    } = useField(
      'field',
      [
        val => (val ? true : REQUIRED_MESSAGE),
        val => ((val as string)?.length >= 3 ? true : MIN_MESSAGE)
      ],
      { bails: false }
    );
    
    Source code(tar.gz)
    Source code(zip)
  • v4.5.10(Mar 8, 2022)

    🐛 Bug Fixes

    • Fixed an issue with da.json locale which caused the JSON file to not parse correctly (94853105e0ca4f425a2c6b5bb7cea2233ec7480d)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.9(Mar 8, 2022)

    🐛 Bug Fixes

    • Set meta.validated for fields validated by the form API's validate (ad9fa9d853a8cabb26cdde04c20c07d4f2673aa4)

    🌏 i18n

    • Updated locale for ko, ja, zh-CN, zh-TW (d5fc7325a943bd6e42d19fa0b6057648d689be80)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.8(Jan 23, 2022)

    🐛 Bug Fixes

    • Fixed a general issue when a field changes its name and has errors at the old name path #3664 (f736e62b1bb82f940d14d74a6d505c913c1c3dde)
    • Fixed an issue where FieldArray.swap function wasn't working when either indices had falsy values (40afbd9cc3fb3de71de3f6ebb0a1b2774d9018ff)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.7(Dec 7, 2021)

    🐛 Bug Fixes

    • Always ensure update:modelValue listener existing on field binding object #3583 (6a53e80525a9c38ce8851407b832bc8409c3f334)

    🌏 i18n

    • Added Uzbek locale thanks to @akahon (#3601)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.6(Nov 17, 2021)

    🐛 Bug Fixes

    • Use watchEffect to calculate FormContext.meta instead of computed #3580 (e8729dc72d2a027a666515360c9537a62a8d46ad)

    As a result of this, there should be a performance improvement depending on the size of your forms

    👕 TypeScript

    • Corrected the typings for resetField #3568 (4e9460e3a4f51f4a78ddcdf17f7c3073f899404f)

    🌏 i18n

    • Added missing Estonian locale messages and fixes by (#3584) @Tarinu
    Source code(tar.gz)
    Source code(zip)
  • v3.4.14(Nov 8, 2021)

  • v4.5.5(Nov 1, 2021)

    🐛 Bug Fixes

    • Fixed an issue where singular checkboxes would be toggled when the form is reset #3551 (cad12ba7502af7268029930a9176d8e160efeef6)
    Source code(tar.gz)
    Source code(zip)
  • v4.5.4(Oct 20, 2021)

  • v4.5.3(Oct 20, 2021)

  • v4.5.2(Sep 30, 2021)

  • v4.5.1(Sep 29, 2021)

  • v4.5.0(Sep 26, 2021)

    🆕 New Features

    Field Arrays

    A long-requested feature is a proper way to handle field arrays. With this release you get two ways you can manage your array fields:

    • useFieldArray a composition API version. Read more in docs
    • <FieldArray /> a component API version. Read more in docs.

    Both have the same API, and they make managing those fields much easier.

    Invalid Submission Handler

    Another common request is the ability to handle invalid submissions, for example, you may want to scroll to the first invalid element.

    This is now possible with both <Form /> component and useForm composition function. Check the links for their documentation:

    Devtools Plugin

    vee-validate now ships with its VueDevtools plugin, this will be an invaluable tool to help you debug your forms and their validation state.

    This is the initial release for the plugin, so please report any bugs and suggest any improvements you can think of. 🙏

    Check the guide page.

    💨 Performance Enhancements

    A partial re-write of vee-validate v4 fixed a long-standing performance issue that was reported here #3399

    💀 Breaking Changes

    handleInput is removed from useField after being deprecated since 4.3, you can use handleChange instead of handleInput as follows:

    const { handleChange } = useField('email', {
      validateOnValueUpdate: false
    });
    
    handleChange('value'); // updates the value and validates
    handleChange('value', false); // updates the value without validation
    
    // replace deprecated handleInput with custom one
    const handleInput = (val) => handleChange(val, false);
    

    Note that handleInput prop still exists in <Field /> scope slot. This is only for useField.

    Note: This release was a 2-month work in progress, so there aren't any bug fixes as 4.4.x was already being worked on in parallel to this release, so both 4.4.x and 4.5.0 contain the same bug fixes which won't be mentioned here in the release notes. Check the previous releases for more information.

    Source code(tar.gz)
    Source code(zip)
  • v3.4.13(Sep 16, 2021)

  • v4.4.11(Sep 11, 2021)

    🐛 Bug Fixes

    • Fixed an issue where computed rules triggered validation before the field was explicitly validated (via event trigger or calling validate).
    Source code(tar.gz)
    Source code(zip)
Owner
Abdelrahman Awad
Frontend Engineer. I dabble in Vue.js, Nuxt.js and Node.js
Abdelrahman Awad
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
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
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
✅ 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 Nov 28, 2022
RawModel.js plugin for Vue.js v2. Form validation has never been easier!

vue-rawmodel RawModel.js plugin for Vue.js v2. Form validation has never been easier! This plugin integrates RawModel.js framework into your Vue.js ap

Kristijan Sedlak 81 Nov 24, 2022
Vue.js 2 form component that integrates jQuery Validation and Axios.

vue-vform Vue.js 2 form component that integrates jQuery Validation and Axios. Install Yarn yarn add vue-vform --dev NPM npm install vue-vform --save-

Jose Quintana 15 Nov 24, 2022
Form validation for Vue.js 2.2+

vue-form Form validation for Vue.js 2.2+ Install Available through npm as vue-form. import VueForm from 'vue-form'; // or var VueForm = require('vue-f

null 618 Oct 7, 2022
Vue form components with server-side validation in mind

Vue form components with server side validation in mind About FormVuelar is a set of predefined vue form components which are designed to automaticall

Janis Kelemen 294 Oct 31, 2022
Vue composition function for Form Validation

Form Validation for Vue 3 Vue composition function for Form Validation with async rules. ?? Written in TypeScript ?? Dynamic Form support ?? Light wei

null 18 May 11, 2022
Results of small 30 min online coding challenge + small polishing afterwards. Vue JS login form + Express JS login endpoint with CORS middleware and validation of request

Install dependencies: npm -i install Start FE: npm run serve ./frontend/src/main.js Start BE: node ./backend/controller/index.js ToDo: tests docker-co

Oleksii Dubinin 0 Jan 14, 2022
A Vue.js directive for sending data from form and primitive validation

Vue Form Send A Vue.js directive for sending data from form and primitive validation inputs Installation npm i --save-dev vue-form-send import VueForm

Aleksey Pleshkov 3 Apr 13, 2022
Simple Vue.js form validation library

Simple Vue.js form validation library

null 0 Mar 1, 2020
Vue Form with Laravel Inspired Validation and Simply Enjoyable Error Messages Api

Vue Form with Laravel Inspired Validation and Simply Enjoyable Error Messages Api. (Form Api, Validator Api, Rules Api, Error Messages Api)

Zak Horton 41 Jul 10, 2022
Another validation form for the Vue. Validates input fields of multiple forms and displays errors

vue-coe-validator ✅ Another validation form for the Vue. Validates input fields of multiple forms and displays errors. Note: without any dependencies.

Vinicius Azevedo 13 Jun 5, 2021
Flexible Vue.js form validation directive

Vue form validator A Vue.js directive for form validation Installation npm instal vue-smart-validator --save Getting Started In your scirpt entry poi

mlxiao93 7 Nov 20, 2018
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
Form validation for Vue in composition functions

Form validation for Vue in composition functions

Vanilla IceCream 3 Nov 8, 2022