Remove ref helper from Vuelidate 2
See original GitHub issue- Start Date: (02-12-19)
- Reference Issues:
- Implementation PR:
Summary
Remove the ref
helper from Vuelidate 2’s @vuelidate/validators
package and related validators as it is mostly inconsistent and incompatible with the new build.
Instead of passing strings to reference values or functions, we directly pass a reference to the required properties.
Basic example
For validators like sameAs
or requiredIf
which use the ref
helper internally, users will have to change the way they use those validators.
Instead of passing a string with the name of the reference field, they would need to pass the field itself.
data: ()=>({
form: {
password: '',
confirmPassword: '',
over18: ''
}
}),
validations(){
return {
form: {
password: { required },
confirmPassword: { sameAs(this.form.password) },
over18: { requiredIf(this.someComputedProperty) }
}
}
},
computed: {
someComputedProperty(){}
}
Motivation and Detailed design
Confusing syntax
In the current Vuelidate 0.x implementation, the ref
helper when passed a reference as a string, it only retrieves properties in the same object scope as the currently validated property.
Check the example below:
{
form: {
personal: {
first_name: '',
last_name: ''
},
business: {
email: '',
address: ''
}
}
}
If we want to have access to email
from first_name
we cant do requiredIf('form.business.email')
, we can only access properties inside the personal
property.
To achieve that, we had to pass a function, which then has it’s this
scope bound to the Vue instance or use the passed parentVM
parameter.
Deep property selectors are also not possible with the string
notation, you need to use the function method, mentioned above. (There is a PR for this, but it only works with simple objects, not with arrays, maps and so on).
Incompatible with Composition API
As Vuelidate 2 is now built with Composition API, and can be used with it, we need to comply with some of the limitations that it brings with it.
- There is no Vue instance yet inside the
setup
hook, which prevents us from binding a validator’sthis
context to it. - We do not have a way to find properties inside the parent object.
Drawbacks
- Users will have to use a function for
validations
opposed to a simple object, to have access to component state. - Not backwards compatible. A manual rewrite on custom written validators using
ref
is needed + update the usage forsameAs,requiredIf,requiredUnless
. - All custom validators need to return a higher order function, which returns a validator
- For simple use cases, it may be a bit more boilerplate to pass a reference than just the property name of the state -
sameAs('password')
vssameAs(this.form.personal.passsword)
.
// OLD WAY
// definition
const oldComparisonValidator = value => ref('someProp') === value
// usage
{
name: { isEqualToSomeProp: oldComparisonValidator }
}
// NEW WAY
// definition
const newComparisonValidator = compareTo => value => value === compareTo
// usage
{
name: { isEqualToAnything: newComparisonValidator(this.someProp) }
}
Alternatives
- We leave it as is, and those validators and helpers just dont work with composition api (worst case)
Adoption strategy
- The
validations
property would need to be transformed to a method:
// from
{
validations: { ... }
}
// to
{
validations() {
return {...}
}
}
- All custom validators using a
ref
would need to be re-written into higher order functions like:
// before
const validator = (value) => value === ref('someValue')
// after
const valudator = (referenceToCompare) => (value) => value === referenceToCompare
Unresolved questions
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:18 (8 by maintainers)
Yeah there is - https://github.com/vuelidate/vuelidate/tree/next
I am going to close this for now, as we removed the ref helper.