vee-validate 3.x 跨域验证 [英] vee-validate 3.x cross field validation
问题描述
我有组件 FromTo,它需要 2 个 Timepicker 组件并交叉验证一个 Timepicker 组件 (From) 到另一个 (To).对 timepicker 应用了 greater vee-validate cross-field 规则,如下所示:
扩展(更大",{参数:[目标"],验证(值,{目标}){let regex = new RegExp("\d{2}:\d{2}", "g");console.log("来自是"+目标);//打印@from 而不是@from 值console.log("值为"+value);返回 regex.test(value)&®ex.test(目标)&&价值 >目标;},消息:To 字段必须大于 from 字段"});
组件体看起来像这样
<div class="flex mb-16 flex-wrap w-full"><div class="mr-1"><label class="font-bold block">来自</label><ValidationProvider name="from" rules="required|time" v-slot="{ errors }"><VueTimepickerv-model="val.from"接近完成:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"/><span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length">{{ 错误[0] }} </span></ValidationProvider>
<div><label class="font-bold block">To</label><ValidationProvider name="to" rules="required|time|greater:@from" v-slot="{ errors }"><VueTimepickerv-model="val.to"接近完成:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"/><span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length">{{ 错误[0] }} </span></ValidationProvider>
</ValidationObserver>
我可以看到我的规则被定位,但控制台记录的是 @from 而不是 @from 值.根据 vee-validate 文档,为了使跨领域验证规则起作用,必须满足以下条件:
<块引用>将字段包装在同一个 ValidationObserver 组件中.目标字段必须具有名称或 vid 属性.在其他规则中正确引用目标字段名称或vid值.
我也正确引用了字段
<块引用>要引用另一个字段的值,请在参数的开头添加 @ 以通知 vee-validate 它应该用目标字段值替换该参数.因此,您将获得字段的值,而不是获得静态的确认"字符串.
我知道我可以像这样定位静态值:
rules=`required|time|greater:${this.from}`
但我真的很想使用@ 符号来定位字段值.我已经尽可能简化了这个例子,所有内部的 v-model 绑定都是正确的.(从、到和整个组件).一段时间以来,我一直在思考这个问题,并仔细阅读了红色文档,非常感谢您的帮助...
我将您的验证功能更改为如下所示:
extend("更大", {参数:[目标"],验证(值,{目标}){let regex = new RegExp(/^\d{2}:\d{2}$/);返回 regex.test(value) &®ex.test(target) &&价值 >目标;},消息:To 字段必须大于 from 字段"});
主要的事情不是添加 "g"
因为它在这里没有做你想要的.除此之外,我认为您唯一真正的错误是您使用的是哪个版本的 vee-validate.如果你使用最新的(3.2.0),你的代码大部分都可以工作,它肯定会传递@from"的值而不是那个字符串.
请参阅此处了解基于您的代码的工作示例:https://codesandbox.io/s/veevalidate-30-cross-field-validation-9nebh
我删除了时间"验证器,因为您的 greater
验证器似乎已经在做同样的事情,而且我没有它的代码.
I have component FromTo that takes 2 Timepickers components and cross validate one Timepicker component (From) to another (To). To timepicker has a greater vee-validate cross-field rule applied to it that looks like this:
extend("greater", {
params:["target"],
validate(value, {target}){
let regex = new RegExp("\d{2}:\d{2}", "g");
console.log("from is "+target); // prints @from instead of @from value
console.log("value is "+value);
return regex.test(value)
&& regex.test(target)
&& value > target;
},
message: "To field must be greater that from field"
});
Component body looks like this
<ValidationObserver>
<div class="flex mb-16 flex-wrap w-full">
<div class="mr-1">
<label class="font-bold block">From</label>
<ValidationProvider name="from" rules="required|time" v-slot="{ errors }">
<VueTimepicker
v-model="val.from"
close-on-complete
:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"
/>
<span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length"> {{ errors[0] }} </span>
</ValidationProvider>
</div>
<div>
<label class="font-bold block">To</label>
<ValidationProvider name="to" rules="required|time|greater:@from" v-slot="{ errors }">
<VueTimepicker
v-model="val.to"
close-on-complete
:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"
/>
<span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length"> {{ errors[0] }} </span>
</ValidationProvider>
</div>
</div>
</ValidationObserver>
I can see my rule being targeted but console logs @from instead of @from value. According to vee-validate docs in order for cross-field validation rule to work following criteria must be met:
Wrap the fields within the same ValidationObserver component. The target field must have a name or vid prop. Properly reference the target field name or vid value in the rules of the other.
I have also properly referenced from field
To reference another field's value, add a @ at the beginning of a param to signal to vee-validate that it should substitute the param with the target field value. So instead of getting a static "confirm" string, you will get the field's value instead.
I know I could possibly target static value like this:
rules=`required|time|greater:${this.from}`
But I would really want to target field values using @ sign. I 've simplified this example as I could and all the inner v-model bindings are correct. (from, to and entire component). I've been breaking my head around this for quite some time and red documentation carefully and would really appreciate any help...
I changed your validation function to look like this:
extend("greater", {
params: ["target"],
validate(value, { target }) {
let regex = new RegExp(/^\d{2}:\d{2}$/);
return regex.test(value) && regex.test(target) && value > target;
},
message: "To field must be greater that from field"
});
The main thing is not adding the "g"
because it doesn't do what you want here. Beyond that, I think your only real error is which version of vee-validate you're using. If you use the latest (3.2.0), your code mostly works and it certainly passes the value of "@from" not that string.
See here for a working example based off your code: https://codesandbox.io/s/veevalidate-30-cross-field-validation-9nebh
I removed the "time" validator because your greater
validator seems to do the same thing already, and I didn't have the code for it anyways.
这篇关于vee-validate 3.x 跨域验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!