iView中表单(动态)Form的校验

1、固定表单校验
对于这类校验,iview的文档说的很易懂,在Form上设置属性model(表单数据对象)和rules(表单验证规则),FormIten上设置属性prop(对应表单域 model 里的字段,user)。具体如下:

<template>
    <Form ref="formInline" :model="formInline" :rules="ruleInline" inline>
        <FormItem prop="user">
            <Input type="text" v-model="formInline.user" placeholder="Username">
                <Icon type="ios-person-outline" slot="prepend"></Icon>
            </Input>
        </FormItem>
        <FormItem>
            <Button type="primary" @click="handleSubmit('formInline')">Signin</Button>
        </FormItem>
    </Form>
</template>
<script>
    export default {
        data () {
            return {
                formInline: {
                    user: ''
                },
                ruleInline: {
                    user: [
                        { required: true, message: 'Please fill in the user name', trigger: 'blur' }
                    ]
                }
            }
        },
        methods: {
            handleSubmit(name) {
                this.$refs[name].validate((valid) => {
                    if (valid) {
                        this.$Message.success('Success!');
                    } else {
                        this.$Message.error('Fail!');
                    }
                })
            }
        }
    }
</script>

1、动态表单校验
对于这类校验,iview的文档不好理解,api的demo看不懂,尤其是**:prop=“‘items.’ + index + ‘.value’”,让人想不通,感觉不合逻辑。我也是试了多次才理解了demo,记录下。
(1)api文档中的说 当需要动态维护 FormItem 时,也可以直接给 FormItem 设置属性 rules 来单独为该域做验证。动态设置 FormItem 的 prop 属性时,会依据上层的 Form 组件的 model 来获取 意思是动态表单的校验要 在FormItem上单独设置rules 和prop ,不是在Form上
(2)prop如何传?
demo中是这样传的
:prop=“‘items.’ + index + ‘.value’”,它的结构是数组变量名 + 遍历索引 + 元素属性名**,它的表单数据结构如下:

    formDynamic: {
         items: [
             {
                 value: '',
                 index: 1,
                 status: 1
             }
         ]
     }

正常的要拿到value值应该items[index].value,但是对于动态表单字段value来说应该设置成items.0.value,其中,数组变量名为items, 遍历索引为v-for中的index,元素属性名为value,因此,在考虑要遍历,写成动态的就是**:prop=“‘items.’ + index + ‘.value’”**,这下清楚了吧。
探究原理,找到FormItem源码,路径node_modules/view-design/src/components/form/form-item.vue,在源码中找到答案,

computed:{
	fieldValue () {
		// FormInstance是当前Form的实例,获取到model,也就questionFormData
		const model = this. FormInstance. model;
		if (!model|I ! this.prop) { return; }
		//此处的prop就是quest ions .0. question
		let path = this . prop;
		//如果遇到:就替换为点,如questions :0.question -> questions .0.question
		if (path. index0f(':') !== -1) {
		path = path.replace(/:/, '.');
		//获取到questions .0. question在questionFormData的值
		return getPropByPath(model, path).v;
		function getPropByPath(obj, path) {
		// temp0bj = questionFormData
		let temp0bj. = obj;
	//将中括号替换为.如questions[0][question] -> questions .0. question
		path = path.replace(/\[(\w+)\]/g, ' .$1');
	//替换首个.questions .0.question -> questions .0.question 最终处理成这个格式
		path =. path.replace(/^\./ ,
		//分割成数组得到['questions','0', 'question']
		let keyArr = path.split('.');
		leti=0;
		//以i = 0来查此处代码作用
		for (1et len = keyArr .length; i < len - 1; ++i) {
		// key = questions
		let key = keyArr[i];
		// questions 在questionFormData中, 进入为true的代码块
		    if (key in temp0bj) {
		      // temp0bj = questions
		      tempobj = temp0bj[key];
		    } else {
		      throw new Error('[iView warn]: please transfer a valid prop path to form item!
		return {
		        o: temp0bj, // { id: 1, question: ' 问题1’}
		        k: keyArr[i]// question
		        v: temp0bj[keyArr[i]] //问题1
		      }
	    }

原来是通过.去分割为数据,数组的值以key的形式去访问model对象,匹配上对应的值。当匹配不上值是会抛出’[iView warn]: please transfer a valid prop path to form item!'错误。
(2)rules如何设置?
第一种,按照demo中的在FormItem上单独设置rules,用于校验简单的情况,如: :rules=“{required: true, message: ‘Item ’ + item.index +’ can not be empty’, trigger: ‘blur’}”
第二种,在data中单独设置,适合于复杂,需自定义规则的情况
如下:

      <template>
		<FormItem style="width: 200px" :prop="'childrens.' + idx + '.minVal'" :rules="dynamicRules.minonGetIndex(index)" v-model="list.minVal" controls-outside :step="0.1">
		           </InputNumber>
		       </FormItem>
      </template>
data(){
    const validateCheckMax = (rule, value, callback) => {
      let field = rule.field || rule.fullField
      let index = Number(field.substr(field.indexOf('.') + 1, 1))
      if (Number(value) < this.datalist[this.formItemIndex].childrens[index].minVal) {
        if (!this.formErrorList.includes(rule.field)) {
          this.formErrorList.push(rule.field)
        }
        callback(new Error('最大值不能小于最小值!'));
      } else {
        callback();
      }
    };
    const validateCheckMin = (rule, value, callback) => {
      let field = rule.field || rule.fullField
      let index = Number(field.substr(field.indexOf('.') + 1, 1))
     // 单独校验最小值
      let temp = 'formDynamic' + this.formItemIndex
      this.$refs[temp + index][0].validateField('childrens.' + index + '.minVal')
      
      if (Number(value) > this.datalist[this.formItemIndex].childrens[index].maxVal) {
        callback(new Error('最小值不能大于最大值!'));
      } else {
        callback();
      }
    };
return{
dynamicRules: {
        max: [
          {
            validator: validateCheckMax
          }
        ],
        min: [
          {
            validator: validateCheckMin
          }
        ]
      },
}
}

参考文档
1、https://www.codenong.com/cs107086780/
2、https://www.jb51.net/article/272950.htm

你可能感兴趣的:(记录,view,design,前端,iview)