Promise实现子组件的多表单校验并反馈结果给父组件

2020-07-26 05:07:16 执剑追风 70 前端开发 / VUE

VUE中进行组件化开发时,当面对一个复杂的表单,需要折分成很多子组件,那么如何进行各子组件表单的验证呢?

先画个图看看整个组件+表单的结构(本文列举4个子组件、子组件中4个子表单为例,更多的同理):

F.vue:父组件,做表单的统一验证和提交;

X.vue:子组件,单独做表单验证,验证通过则提交表单数据给父组件;

formX:子组件中表单绑定的model变量,通常所有子表单绑定在这一个表单变量上;

form_xn:子表单的ref;

 

注:本文中表单验证基于Element-ui实现(采用ref+validate方法实现,但整体框架具备通用性)

 

一、Promise实例生成

首先需要一个根据ref动态生成Promise实例(可以理解为后面需要并行的任务)的公共方法:

复制代码

// 根据表单ref,动态生成Promise,参数传递ref的name数组
formPromiseArray(vm, formName) {
  let promiseArray = []
  for (var i in formName) {
    let promise = new Promise(function(resolve, reject) {
      vm.$refs[formName[i]].validate((valid) => {
        if (valid) {
          resolve()
        } else {
          reject(new Error())
        }
      })
    })
    promiseArray.push(promise)
  }
  return promiseArray
}

复制代码

二、子组件表单校验

在子组件中利用Promise.all实现多个子表单并行校验,只有当所有子表单均通过验证时才给valid变量赋值为true:

复制代码

// 表单验证
async validateForm() {
  let vm = this
  let promiseArray = util.formPromiseArray(vm, ['form_a1', ' form_a2', ' form_a3', ' form_a4'])
  await Promise.all(promiseArray).then(() => {
    vm.valid = true
  }).catch(() => {
    vm.valid = false
  })
}

复制代码

三、提交表单数据给父组件

当子组件表单校验通过后,将最新的表单数据对象返回给父组件:

复制代码

// 用于父组件触发,传递最新表单数据
async submitForm() {
  await this.validateForm()
  if (this.valid) {
    let form = _.cloneDeep(this.formA)
    return form
  }
}

复制代码

四、父组件获取子组件的表单数据

父组件提交保存请求前校验子组件表单,当校验通过时获取子组件表单数据(父组件中子组件ref为child,通过调用子组件方法获取表单数据):

复制代码

// 获取最新表单数据并封装成对象,根据是否返回对象确定校验是否通过
async submitForm() {
  let form = {
    recordId: this.recordId 
  }
  let vm = this
  await this.$refs.child.submitForm().then(obj => {
    vm.isPassA = !!obj
    if (obj) {
      form.formAData = _.cloneDeep(obj)
    }
  })
    return form
}

复制代码

五、父组件提交保存请求

当所有表单校验通过时才提交保存:

复制代码

// 保存处理进度
save () { 
  let vm = this
  this.submitForm().then((form) => {
    if (vm.isPassA && vm.isPassB && vm. isPassC && vm. isPassD) {
      // 提交保存请求
    } else {
      vm.$message.info('请检查信息格式')
    }
  })
}

复制代码

至此,整个多表单验证就完成了,在父组件中还可以根据子组件返回的校验结果设置子组件表单未通过验证的样式,例如小红点标识。


转载自:https://www.cnblogs.com/dreamsqin/p/11529207.html