Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upVeeValidate v3.0 🚀 #2191
Comments
This comment has been minimized.
This comment has been minimized.
The scope could be useful. If for example you are using a tabbed panel/form, and every tab is a component, you could detect an error in any component and disable, for example, the whole form submit button. But let's assume the error is in a tab which is hidden, and thus the user sees the disabled form submit button, but doesn't understand in which tab the error may be. Instead, if you assign a scope to all fields of a given tab of the form, you could quickly check in what scope the error is and notify the user by, for example, highlighting in red the tab title. Thank you for your work! |
This comment has been minimized.
This comment has been minimized.
Is there any timeframe for a beta of the version 3 release? |
This comment has been minimized.
This comment has been minimized.
@fessacchiotto You could use multiple observers and have them under one parent observer, which would give you what you need as you could check the whole state of the forms or individual tabs by checking each observer. I will include this use-case in the docs as I think its fairly common. You can use the current Provider/Observer components as they didn't change a lot in |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
vee-validate is out, looking forward to your feedback! |
This comment has been minimized.
This comment has been minimized.
@logaretm Thanks for the heads up! I will give it a shot Monday and see :) |
This comment has been minimized.
This comment has been minimized.
@logaretm is migration guide to version 3 available anywhere? I couldn't find it. |
This comment has been minimized.
This comment has been minimized.
Have not seen one either, but here is an instructive article: https://www.baianat.com/labs/code/veevalidate-3-0 @Loremaster |
This comment has been minimized.
This comment has been minimized.
@bodograumann thanks for that! I have seen that already and was hoping for more in depth guide :) |
This comment has been minimized.
This comment has been minimized.
The guide hasn't been written yet, I plan to have one in a couple of days
if nothing comes up.
…On Fri, Aug 30, 2019, 3:26 PM Serj L ***@***.***> wrote:
@bodograumann <https://github.com/bodograumann> thanks for that! I have
seen that already and was hoping for more in depth guide :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2191>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABPYUSWEVPCOEEWSU3FKU73QHENXNANCNFSM4IHSLYMQ>
.
|
This comment has been minimized.
This comment has been minimized.
@logaretm Thank you! Will be waiting for that. |
This comment has been minimized.
This comment has been minimized.
@logaretm any updates on the migration guide? |
This comment has been minimized.
This comment has been minimized.
I too am looking for a migration guide. We moved away from the directive a long time ago in favour of validation components, and I'm more interested in adding in a few rules that were removed. How would the |
This comment has been minimized.
This comment has been minimized.
@logaretm , please, is there something close to a migration guide? Thank you! |
This comment has been minimized.
This comment has been minimized.
The new version has removed some rules which are easy to implement, however, as I can see from https://github.com/validatorjs/validator.js/blob/master/src/lib/isURL.js here, it's not that easy actually to implement url rule :( |
This comment has been minimized.
This comment has been minimized.
@logaretm Really appreciate all the effort that went into v3 and look forwarding to using it, however a migration guide would be really helpful. |
This comment has been minimized.
This comment has been minimized.
@victor-ponamariov > my workaround to implement it: extend('url', {
validate: (str) => {
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
return !!pattern.test(str);
},
message: 'This is not a valid URL'
}) Regex from Zemljoradnik |
This comment has been minimized.
This comment has been minimized.
@logaretm any updates? |
This comment has been minimized.
This comment has been minimized.
While I understand all the reasons behind your design decisions, I will stick with using v2 because it doesn't inject random tags in the DOM that mess with the styling and layout of the form. |
This comment has been minimized.
This comment has been minimized.
Won’t the bee-validate support (https://github.com/logaretm/vue-use-form/blob/master/README.md) for the new vue composition API solve this issue?
…> On 10 Nov 2019, at 01:31, mattsteve ***@***.***> wrote:
While I understand all the reasons behind your design decisions, I will stick with using v2 because it doesn't inject random tags in the DOM that mess with the styling and layout of the form.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
This comment has been minimized.
This comment has been minimized.
@mattsteve, random tags? Don't we have control over them? |
This comment has been minimized.
This comment has been minimized.
@mattsteve It's far from random, they always render a |
This comment has been minimized.
This comment has been minimized.
@logaretm "random" in terms of "not designed for the layout". I was unaware of the slim prop, but at the same time it's not a perfect solution since it only takes 1 child. |
This comment has been minimized.
This comment has been minimized.
Any update on that migration guide? I don't see how we can update our version to v3 without any form of guide... |
This comment has been minimized.
This comment has been minimized.
I'm working on it at the moment as part of the new docs, the changes can be tracked here: https://github.com/logaretm/vee-validate/tree/docs/change-structure I'm trying to build a more interactive experience in the migration guide, as it is a totally different concept and there is no simple steps to follow. Also, vee-validate surface area is large as it handles localization and arbitrary validation as well, so covering the changes in those areas is tricky. I'm aiming to release |
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
.Goals
The goals of this release are as following:
v-validate
directive deprecation.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
andfields
. 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. Evenvee-validate
name is a pun for thev-validate
directive.But to list the directive problems:
data-vv-*
attributes which aren't reactive, are repetitive and will add clutter your template.errors
andfields
to be present.v-if
andv-for
caveats which aren't apparent to the developer at first glance.Scopes
API which is often confused withValidation Scope
, also adds clutter to your template.Provider/Inject
API which is not recommended for public use.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 todata-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 callederrors
, this causes a problem for maintenance sake as it is not immediately clear where diderrors
come from, which is the same downsides for using global mixins. Your teammates simply had to know that the project is usingvee-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 likevuex
. I originally intended for the directive to be inv3
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
andv-for
caveatsThe 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 theconfirmed
rule and any cross-field rule would never work across components as they rely on therefs
present in the context of thev-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 timeerrors.first
anderrors.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:
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
andvalidateAll
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
andValidationObserver
components recently whenever anyone faces one of the above problems. They will be the primary way to usev-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 thefunction 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 upValidationProvider
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. Sov3
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
APIUsed to be the
verify
API, It is stateless, unlike the oldValidator
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:
extend
APIUsed to be the
Validator.extend
method.There are a few problems with the current rule system, especially for Date/Cross-field rules:
date-fns
implementation which lacks proper timezone support.required
.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 thevalue
prop.The proposed API looks like this:
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
vsstring
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 aparams
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: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.A11y
VeeValidate offered basic accessibility features in
v2
and inv3
it will go a step further.ariaInput
The
ValidationProvider
slot props expose anariaInput
object which you can bind to your inputs:ariaMsg
ariaMsg
is another set of aria attributes, but you bind it to your error display element. A full example would look like this:localize
API and i18nThe 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 forVueI18n
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 theValidator.localize
method of the old API.The full dictionary looks like this:
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 internali18n
dictionary used by vee-validate. But if you want to run your own solution likeVueI18n
you could do so while installing rules: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:With that being said, the message generator signature was changed to look like this:
Which means
params
anddata
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 anyi18n
implementation out there.Bundle-size
Few rules were removed due to their size and they are very easy to implement:
This means vee-validate no longer depends on
validator.js
and will allow you to use whatever version ofvalidator.js
to add the rules you need without conflicts from vee-validate internal copy of it.Some rules behavior has been changed:
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:
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