vue-element-admin中的多个表单共享验证rule

前因

有个业务需求为 表单中有两个字段 一个是 最小长度input输入框 一个是最大长度input输入框 因为要联动判断两个输入框的值,最小不能大于最大 最大不能小于最小,去官方翻例子发现只有一个自定义验证并且案例写的比较模糊

el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <el-form-item label="密码" prop="pass">
    <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="确认密码" prop="checkPass">
    <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="年龄" prop="age">
    <el-input v-model.number="ruleForm.age"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>
<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('年龄不能为空'));
        }
        setTimeout(() => {
          if (!Number.isInteger(value)) {
            callback(new Error('请输入数字值'));
          } else {
            if (value < 18) {
              callback(new Error('必须年满18岁'));
            } else {
              callback();
            }
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ],
          age: [
            { validator: checkAge, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

模糊的地方有两点 首先是el-form-item中的prop传递的是rule中的key还是model中的key,后来往下翻官方文档发现传递的是model中的key。
那么问题又来了,表单item的验证规则能否自定义?往后翻了一下看到有个rules属性 但是官方写的rules 表单验证规则 object- -明明也可以传递Array,虽然在JS中Array的确属于Object。
吐槽完了后再回到业务需求。

首先有多个表单,那么model肯定是form[x],但是rules是rule这一个变量,多个表单都有判断最小长度和最大长度的需求,但是在自定义验证规则的函数中你是不知道当前是哪个表单在验证。所以就很蛋疼.所以后面摸索了一下 发现可以用key作为标记点这么玩

<el-form ref="form[0]" :model="form" :rules="rules" label-width="80px">
              <el-form-item label="字段名称" prop="name">
                <el-input v-model="form.string.name" />
              </el-form-item>
              <el-form-item label="字段key">
                <el-input v-model="form.string.key" />
              </el-form-item>
              <el-form-item label="是否必填">
                <el-switch v-model="form.string.require" />
              </el-form-item>
              <el-form-item label="唯一属性">
                <el-switch v-model="form.string.unique" />
                <span>如果提交存在相同的值则不让创建</span>
              </el-form-item>
              <el-form-item data-id="233" label="最小输入长度" :rules="rules.cminlen" prop="string.minLength">
                <el-input v-model="form.string.minLength" type="number" :min="1" />
              </el-form-item>
              <el-form-item label="最大输入长度">
                <el-input v-model="form.string.maxLength" type="number" :min="1" />
              </el-form-item>
              <el-form-item>
                <el-button @click="saveModelType('form[0]')">保存</el-button>
              </el-form-item>
            </el-form>
// script
form:{
string:{}
}
const validateMinLen = (field, value) => {
      console.log('validateMinLen', field, value)
      const form = this.getFieldForm(field.fullField)
      console.log('form',form)
    }

注意看prop="string.minLength",那么在自定义函数中的field可以拿到当前的propstring.minLength,接下来就很简单了

getFieldForm(fieldName) {
      // 解析fieldName
      const arr = fieldName.split('.')
      return this.form[arr[0]]
    },

写个函数以.分隔一下即可拿到当前属于的form,这个时候就可以联动判断了。