1.对校验项进行手动触发校验
配置 VeeValidate 时,触发事件event设置为‘blur’,而表单在点击提交按钮时,没有对整个表单进行校验,用户如果点开配置表单,不做任何操作就提交的话,会导致页面上不会有任何反应,因此调用 VeeValidate手动触发函数this.$validator.validate(),进行整体校验
this.$validator.validate()会返回promise, resolve的回调函数的参数result 为false时校验不通过,true时校验通过
2.添加select 验证
因为 VeeValidate 只对 input 进行,所以当表单配置项以select呈现时,就算在标签上添加v-validate,也不会对其进行校验,反而还会导致之前配置的blur触发事件失效,所以手动添加对select的校验
之前调用this.$validator.validate()进行手动触发校验input ,返回的是promise,因此在校验完input之后先不管input的校验结果,直接对select 进行校验
select 出现在配置项中有两种情况,一种是通过配置表单时,配置过来的,另外一种是通过slot套嵌进来的,slot也属于配置对象config里面的一种type
之所以会出现需要通过slot 来添加select的情况,是因为这类的select一般需要绑定change事件,与其他配置项形成关联关系,如果以配置项的方式给select添加绑定change事件,会导致infinity loop错误,
导致出现这个错误的原因是渲染配置项的时候用的是一个v-for,一项一项把配置的input,select根据type渲染出来,这时,如果给select绑上change事件,而且change事件的内容是对v-for的对象的属性进行修改vue的机制就会认为触发了无限循环,开始死循环,因此不为配置的项添加change事件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26父组件配置对象
modelConfig: {
title: '授权',
modalId: 'modelConfig',
isAdd: true,
config: [
{label: '策略', value: 'v_policy_selected', option: 'v_policy_option', placeholder: '', disabled: false, type: 'select',v_validate: 'required:true',isError: false},
{name: 'selectAz', type: 'slot', v_validate:[
{label: '租户', value: 'v_tenant_selected', isError: 'v_tenant_isError', type: 'select'},
{label: '项目', value: 'v_project_selected', isError: 'v_project_isError', type: 'select'}
]}],
addRow: { // 其他配置项绑定的数据
},
v_select_configs: {
v_policy_selected: null, // 选中数据
v_policy_option: [], // 选择数据
v_project_selected: null, // 选中数据
v_project_option: [], // 选择数据
v_project_isError: false,
v_tenant_selected: null, // 选中数据
v_tenant_option: [], // 选择数据
v_tenant_isError: false
},
saveFunc: 'authSave'
}
主要验证逻辑如下:
校验之前设置flag = true,标志select的校验结果,最后用于与input校验结果result共同决定校验结果
先判断该配置项是否显示在表单中,因为有时新增和编辑的配置项不同,如果不在就不对该项进行校验,continue
对通过配置项展示的select,进行校验,如配置了校验规则v_validate,而且值为未选状态,则显示校验错误提示,同时设置flag = false,否则,不显示校验错误提示
这种错误提示同input,其显示通过配置项对象里面的一个属性决定,因此效果就是,显示提示该属性就设为true,否则设为false1
2<label v-show="errors.has(item.value) && isHide(item.hide)" class="col-md-7 help is-danger">{{item.label}} {{errors.first(item.value)}}</label>
<label v-if="item.type === 'select' && item.isError" class="col-md-7 help is-danger">{{item.label}} 不能为空</label>
对通过slot展示的select, 进行校验, 所有需要校验的配置放在v_validate属性中,遍历v_validate,判断select的值是否为未选,未选则显示提示,已选则不显示
错误提示放在slot的代码中,每一项配置自己的错误提示label,label的显示通过v_validate里面每一项配置的对应的错误提示属性的绑定值决定1
2
3
4
5
6
7
8
9
10
11<div slot="selectAz">
<v-select
v-model="modelConfig.v_select_configs.v_region_selected"
label="name"
class="col-md-7 v-selectss "
:on-change="changeRegion"
:options="modelConfig.v_select_configs.v_region_option">
</v-select>
<label class="required-tip">*</label>
<label v-if="modelConfig.v_select_configs.v_region_isError" class="col-md-7 help is-danger">xxx 不能为空</label>
</div>
1 | 具体代码 |
3.勾选选项后错误消失
在公共组件里面为prop添加watch方法,当对象属性发生变化时就检查select是否有值了,有的话,就将提示隐藏掉
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31data () {
return {
configCopy:this.modelConfig,
FLAG:false
}
},
props: ['modelConfig'],
watch:{
configCopy: {
handler(){
//select选择完将提示隐藏,如果日后保留'X'删除功能,如需要,再增加显示处理逻辑
for(let key in this.modelConfig.v_select_configs) { //slot select
if(key.endsWith('isError')){
let prefix = key.slice(0,-7)
if(this.modelConfig.v_select_configs[key] && this.modelConfig.v_select_configs[prefix+'selected']){
this.modelConfig.v_select_configs[key] = false
}
}
}
for(let i=0; i< this.modelConfig.config.length; i++){ //config select
if(this.modelConfig.config[i].type === 'select' && this.modelConfig.config[i].v_validate) {
let obj = this.modelConfig.config[i]
if(this.modelConfig.v_select_configs[obj.value]){
this.modelConfig.config[i].isError = false
}
}
}
},
deep:true
}
},
4.关闭配置页面的清空
检查配置项对象里面所有的select配置项,将其负责错误提示显示的项设置为false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 清除表单selected
for(let i=0; i<this.modelConfig.config.length; i++){
if(this.modelConfig.config[i].type === 'select' && this.modelConfig.config[i].v_validate) {
this.modelConfig.config[i].isError = false
}
if(this.modelConfig.config[i].type === 'slot') {
let arr = this.modelConfig.config[i].v_validate ? this.modelConfig.config[i].v_validate :[]
for(let j =0;j<arr.length;j++){
let key = arr[j].isError
let value = arr[j].value
if(arr[j].type === 'select' && !this.modelConfig.v_select_configs[value]) {
this.modelConfig.v_select_configs[key] = false
}
}
}
}