需求
有一个长度为n的对象数组,对象的结构和属性一样,属性值不同。每一个对象都是一个表单数据 formData
。
如下图所示,左侧为菜单,点击设置当前表单展示的数据,右侧表单展示左侧的表单数据,即arr[k] = formData
,在提交表单时,需要逐个校验arr[k]
的必填项,校验通过则可提交,不通过则将表单停留在当前不通过的表单上,页面滚动到当前未填字段位置
知识点
promise
异步、组件渲染
思路
遍历菜单数组,设置当前表单formData
的数据,返回一个promise
,利用await
关键字同步校验当前表单,因为用到表单的实例方法validate
,需要等组件渲染完才能进行下一组数据的校验,所以需要用到this.$nextTick
代码
// 校验所有表单
function validateAllForm(){
let validateResult = true //整个数组验证结果
let len = this.data.length
for(let i=0; i<len; i++){
// 验证当前表单
const isSuccess = await this.checkSingleForm(this.data[i],i)
// 按照顺序验证,如果有一个验证不通过则退出循环,在逻辑上优化性能
if (!isSuccess) {
this.activeMenu = i //设置当前聚焦菜单
this.scrollToRequireField()
validateResult = false
break
}
}
}
// 校验单个表单
function checkSingleForm(item,index){
this.formData = {}
this.formData = item
return new Promise((resolve,reject) => {
this.$nextTick(() =>{
this.$refs['form'].validate((valid) => {
if(valid){
resolve(true)
}else{
resolve(false)
}
})
})
})
}
// 页面滚动到对应位置
scrollToRequireField(){
this.$nextTick(() => {
let scrollElement = ''
let formFieldElement = document.getElementsByClassName('el-form-item__error')
if (formFieldElement && formFieldElement.length > 0) {
scrollElement = formFieldElement
}
scrollElement[0].scrollIntoView()
})
}