This release contains major and breaking changes, I'm very sorry that this is the case but those frequent breaking changes will stabilize as we move towards the full release.
Features
- Dynamic rules. 💯
- Better scoping.
- ES6 Build.
- Smaller bundle size.
- Small improvements.
- Breaking changes 😞
Breaking Changes
Syntax
The validate
directive now accepts either a string or an object literal to configure the field being bound to. the following object structure is considered valid:
<input type="text" name="email" v-validate="expression">
const expression = {
rules: 'required|email',
arg: 'form.email',
scope: 'scope1'
};
If you only need to specify the rules, you can pass it directly, remember that it must evaluated as a string:
const expression = 'required|email';
You can also use object form to specify rules which allows greater flexibility specially with regex rule that had problems and conflicts with the parsing mechanism.
const expression = {
rules: {
required: true,
regex: /.(js|ts)$/,
in: [1, 2, 3]
}
};
But that means you cannot validate data values or computed values in the same way anymore, so you are going to need to pass an arg into either the directive or the expression, like this:
<input type="text" name="email" v-validate:email="{ rules: 'required|email' }">
<!-- OR if you have a nested model you can also do this -->
<input type="text" name="email" v-validate="{ rules: 'required|email', arg: 'email' }">
Note that you can still use data-vv-rules
, as it is not deprecated yet. but moving on to full release it might become.
These changes allows for dynamic rules, by simply binding the expression to a rules value that can be changed, the plugin will pickup when a rule is changed for a specific field and update it accordingly, meaning you can implement complex validation logic like required_if
or some other rules that you can find in Laravel's validations, by updating the rules for that field according to whatever condition you might have.
Scopes
Scoping has been very inconsistent when pushed to certain limits, this had to do with how scopes are internally managed. due to some embarrassing short sight they were stored as keys in $fields
property which of course caused the fields to overwrite each other since they have the same name even if in different scopes.
Scopes are now properly isolated from each other, a field name and its scope are now conditions of its uniqueness.
So here is some valid ways to specify a scope for an input:
<!-- Either on the parent form using the data-vv-scope attribute -->
<form data-vv-scope="myscope">
<input type="text" name="email" v-validate="'required|email'">
</form>
<!-- or in the expression passed to the directive -->
<input type="text" name="email" v-validate="{ rules: 'required|email', scope: 'myscope' }">
<!-- or on inputs using data-vv-scope attribute -->
<input type="text" name="email" v-validate="'required|email'" data-vv-scope="myscope">
By default a scope called __global__
is present at the beginning which is the only scope name reserved that you cannot use, it will hold all non-scoped fields data, but it is also isolated from the other scopes so the following behaviors are changed:
$validator.validate('someField', 'value');
will validate the field calledsomeField
that is located in the__global__
scope. So similar fields in other scope are not affected.errors.first
or similar methods in the errorBag object without specifying a scope will limit the results to the__global__
scope, soerrors.all()
will only return the errors located in the__global__
scope and not all the items.$validator.validateAll
will validate the fields located in the__global__
scope only and not all the fields, alternatively you can use$validator.validateScopes()
to validate all scopes within the validator.
Other
$validator.validateAll returns promise that is now catchable, meaning it will throw an error when a validation fails, enabling you to do:
$validator.validateAll().then(() => {
// success stuff.
}).catch(() => {
// failure stuff.
});
So if you were expecting only a boolean value depending on the validation result, you need to handle it correctly using catch
which should simplify your code considerably.
New Stuff:
errors.first
,errors.has
and also$validator.validate
now support dot notation to access fields with specific scope, for example:
// returns the first error found for the email field located in the scope: 'form1'.
errors.first('form1.email');
// returns the first error triggered by the rule 'required' for the email field
// located inside the scope 'form1'.
errors.first('form1.email:required');
// validate the email field located in form1 scope.
$validator.validate('form1.email', 'someValue');
- The plugin is now back to being built by
rollup.js
which reduced the bundle size down to half. The plugin footprint is around 9kb gzipped and minified. - New ES6 build is now available in
/dist/vee-validate.es2015.js
which should be imported automatically by es module aware bundlers like rollup, which should even cut down the size of your package.