由于需求实在太**,只能把一个大表单分成多个子组件、孙组件甚至重孙组件再去校验,而且其中孙组件还是不确定个数的,(;′⌒`),用到了element的表单校验以及Promise.all

需要在各个组件页面写好能主动触发的校验方法,我是统一都写成一个方法名
各个页面区别主要是,最底层的重孙组件只按照正常的校验写就行,其他上级组件的方法中需要根据下级组件返回结果确定promise出去的结果

重孙组件

validateData() { // 校验
  return new Promise((resolve, reject) => {
    this.$refs.ruleForm.validate(valid => {
      if (valid) {
        resolve("OK"); // 成功的话,返回OK
      } else {
        resolve("err"); // 校验失败,返回err
      }
    });
  });
},

孙组件
此处演示只校验一个重孙组件情况,如果需要校验多个重孙组件,请参考下方子组件校验孙组件方法

validateData() { // 校验
  return new Promise((resolve, reject) => {
    this.$refs.ruleForm.validate(valid => {
      if (valid) {
      	// 此处为校验重孙组件
        this.$refs.chongsun.validateData().then(res => {
          resolve("OK"); // 成功的话,返回OK
        }).catch(err => {
          resolve("err"); // 校验失败,返回err
        })
      } else {
        resolve("err"); // 校验失败,返回err
      }
    });
  });
},

子组件
大招来了,此处分为确定个数孙组件和不确定个数孙组件
确定个数孙组件,直接使用Promise.all即可

validateData() { // 校验
  return new Promise((resolve, reject) => {
    this.$refs.ruleForm.validate(valid => {
      if (valid) {
      	// 此处为校验了两个孙组件
        Promise.all([this.$refs.sun1.validateData(), this.$refs.sun2.validateData()]).then(res => {
          resolve("OK"); // 成功的话,返回OK
        }).catch(err => {
          resolve("err"); // 校验失败,返回err
        })
      } else {
        resolve("err"); // 校验失败,返回err
      }
    });
  });
},

不确定个数孙组件—孙组件是通过循环来的,此处做法我是给所有的孙组件取了统一的ref名
然后校验时会通过一个方法循环校验每个孙组件,一直到确定所有孙组件都校验完成,再根据返回的内容给上级组件返回

validateData() { // 校验
  return new Promise((resolve, reject) => {
    this.$refs.ruleForm.validate(valid => {
      if (valid) {
        
        this.validateDataAll().then(res => { // 根据当前组件内方法的返回确定是否孙组件全校验成功
          if (res == 'OK') {
            resolve("OK");
          } else {
            resolve("err");
          }
        })
      } else {
        resolve("err");
      }
    });
  });
},
validateDataAll() {
  let sum = 0 // 记录下来当前已经有多少个孙组件有返回了
  let arr = [] // 记录下各个孙组件的返回值
  return new Promise((resolve, reject) => {
    this.$refs.sun.forEach((item, index) => {
      item.validateData().then(res => {
        sum++ // 孙组件有返回,+1
        arr.push(res) // 记录下当前孙组件返回的内容
        if (sum == this.$refs.sun.length) { // 相等说明真的全校验完了
          let notAllOK = arr.some((arritem) => { // 如果返回的里面有不是OK的,就说明有校验失败的
            return arritem != 'OK'
          })
          if (notAllOK) {
            resolve("err"); // 不是全OK,说明校验失败
          } else {
            resolve('OK') // 全OK,说明校验成功
          }
        }
      })
    })
  });
},

父组件

validateData() { // 校验
  return new Promise((resolve, reject) => {
    this.$refs.ruleForm.validate(valid => {
      if (valid) {
      	// 此处为校验了两个子组件
        Promise.all([this.$refs.zi1.validateData(), this.$refs.zi2.validateData()]).then(res => {
          resolve("OK"); // 成功的话,返回OK
        }).catch(err => {
          resolve("err"); // 校验失败,返回err
        })
      } else {
        resolve("err"); // 校验失败,返回err
      }
    });
  });
},

方法写好之后,在需要的地方调用校验就可以了

附上一张我此次校验的流程图,看脑图还好,写的时候真的很乱(;′⌒`)

elementui 表单校验长度_前端