elementui e-form中嵌套列表循环验证

现在有一个需求
接口返回一个数组, 需要在页面上渲染。
这些数据,有的是输入框,下拉框,时间选择等,
这些可操作的控件需要有必填验证,长度验证等
有些需要调用接口进行远程验证。
返回的数据比较多,有些数据有200条

就不能在rules里面直接写调用远程接口的验证

// 判定规则
                rules: {
                    password: [{
                            required: true,
                            message: '请输入密码',
                            trigger: 'blur'
                        },
                        {
                            min: 3,
                            max: 15,
                            message: '长度在 3 到 15 个字符',
                            trigger: 'blur'
                        },
                        {
                            trigger: 'blur',
                            //validatePass --- 我们自定义的校验规则
                            validator: validatePass  
                        }
                    ],
                },

const validatePass = (rule, value, callback) => {
                this.$ajax.get({
                    url: '/isNameOnly',
                    config: {
                        params: {
                            password: value
                        }
                    },
                    cb: (res) => {
                        nameOK = res.data == 1 ? true : false
                        if (!!nameOK) {
                          callback()
					    } else {
					      callback(new Error('经验证,该项目已存在于数据库中'))
                        }	
                    }
                })
                
            }

这样是最基本的验证,但在本个例子中不可以。 主要是因为数据比较多,提交校验时没次都会请求接口,导致页面卡住。如有3个字段需要远程校验合法性,所以就有600次请求后台接口

其实,一开始,客户要求,页面渲染的时候就需要展示校验结果。页面初始化的时候就需要validate()方法,导致页面渲染的时候就要请求。那场面锣鼓喧天,页面泛白。

为了解决这个问题
初始化过来的时候,数据中每个数据中要加一个验证字段

[
{
	password: '',
	passwordError: '密码验证有误'
}
]

提交的时候,就不使用接口了,初始化和提交的时候,直接校验这个错误信息是否有值

const validatePass = (rule, row, callback) => {
				if (row.passwordError){// 当passwordError不为空的时候表示验证不通过
                	 callback(new Error(row.passwordError))
                } else {
                	callback()
                }
 }

如何在验证接口中获取row? , 按照文档,校验文档的第二个值是操作的值,而我们在这个自定义验证函数里面要获取当前行的数据中的passwordError,怎么办
终于在同事的帮助下,看到例子

<el-form ref="formData" :model="formData" :rules="formDataRules" label-width="120px">
	<div v-for="(item,index) in formData.list" :key="index">
		<el-form-item :prop="'list.'+ index +'.password'" :rules="formDataRules.password" label="密码">                              
			<el-input v-model="item.password"></el-input>
		</el-form-item>
	</div>
</el-form>

大家想过没有 :prop="‘list.’+ index +’.password’" 这个的作用是什么。 原来一直认为,这是一个固定的写法,用来配合:rules来校验,后来发现 当修改password的时候, 传到validatePass 里面的第二个参数是可变的。这个值是prop传过去的
好了,上面的验证函数就可以获取相应的值了。

我们继续。当改变input的值,我们单独修改对应行的报错信息passwordError

<el-form ref="formData" :model="formData" :rules="formDataRules" label-width="120px">
	<div v-for="(item,index) in formData.list" :key="index">
		<el-form-item :prop="'list.'+ index +'.password'" :rules="formDataRules.password" label="密码">                              
			<el-input v-model="item.password" @change=changePassword($event, item)></el-input>
		</el-form-item>
	</div>
</el-form>


changePassword(value, row) {
		this.$ajax.get({
                    url: '/isNameOnly',
                    config: {
                        params: {
                            password: value,
                        }
                    },
                    cb: (res) => {
                        nameOK = res.data == 1 ? true : false
                        if (!!nameOK) {
                          row.passwordError = ''
					    } else {
					      row.passwordError = '密码验证错误'
                        }	
                    }
                })
}

很遗憾, 因为一些原因
el-form里面嵌套的是el-table(当然如果不是嵌套的el-table)而是如例子显示也会出现bug
操作改变列表里面的值时,虽然调用了接口,但是报错信息,甚至输入的值无法立即渲染

为此我们病急乱投医

changePassword(value, row) {
		this.$ajax.get({
                    url: '/isNameOnly',
                    config: {
                        params: {
                            password: value,
                        }
                    },
                    cb: (res) => {
                        nameOK = res.data == 1 ? true : false
                        if (!!nameOK) {
                          row.passwordError = ''
					    } else {
					      row.passwordError = '密码验证错误'
                        }
                        this.$forceUpdate()
                        this.$nextTick(() => {
                        	this.$refs.elform.validate()
                        })	
                        // setTimeout(() => {
                        	// this.$refs.elform.validate()
                        // }, 400)
                    }
                })
}

如果错误验证还没出来 请使用 注释setTimeout那部分
如果还不行,请检查

// 判定规则
                rules: {
                    password: [{
                            required: true,
                            message: '请输入密码',
                            trigger: 'blur'
                        },
                        {
                            min: 3,
                            max: 15,
                            message: '长度在 3 到 15 个字符',
                            trigger: 'blur'
                        },
                        {
                            trigger: 'blur',
                            //validatePass --- 我们自定义的校验规则
                            validator: validatePass  
                        }
                    ],
                },

输入框要使用 trigger: ‘blur’, 下拉框,日期选择框要使用select

如果还不行还有一种方法

this.formData.list = JSON.parse(JSON.stringify(this.formData.list))
setTimeout(() => {
            this.$refs.elform.validate()
}, 400)

哎…

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值