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.min<InputNumber @on-change="onGetIndex(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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
iview form表单通过校验规则来确保用户输入数据的合法性。但是有时候我们需要移除某些校验规则来满足特定需求。 iview form表单提供了两种方法来移除校验规则,分别是通过表单ref属性和通过字段的prop属性。 通过表单ref属性移除校验规则,需要先获取表单对象,然后调用$refs.formName.removeRule()方法。其formName为表单的ref属性值,removeRule()方法传入的参数为需要移除校验规则的字段的prop属性值。 实例如下: ```html <template> <Form :model="form" :rules="rules" ref="form"> <FormItem label="姓名" prop="name"> <Input v-model="form.name" /> </FormItem> <FormItem label="手机号" prop="phone"> <Input v-model="form.phone" /> </FormItem> <FormItem> <Button @click="removePhoneRule">移除手机号校验</Button> </FormItem> </Form> </template> <script> export default { data() { return { form: { name: '', phone: '' }, rules: { name: [{required: true, message: '请输入姓名', trigger: 'blur'}], phone: [{required: true, message: '请输入手机号', trigger: 'blur'}, {pattern: /^1[3456789]\d{9}$/, message: '手机号格式不正确', trigger: 'blur'}] } } }, methods: { removePhoneRule() { this.$refs.form.removeRule('phone'); } } } </script> ``` 通过字段的prop属性移除校验规则,只需要在校验规则将该字段的校验规则设置为一个空数组即可。 实例如下: ```html <template> <Form :model="form" :rules="rules"> <FormItem label="姓名" prop="name"> <Input v-model="form.name" /> </FormItem> <FormItem label="手机号" prop="phone"> <Input v-model="form.phone" /> </FormItem> <FormItem> <Button @click="removePhoneRule">移除手机号校验</Button> </FormItem> </Form> </template> <script> export default { data() { return { form: { name: '', phone: '' }, rules: { name: [{required: true, message: '请输入姓名', trigger: 'blur'}], phone: [{required: true, message: '请输入手机号', trigger: 'blur'}, {pattern: /^1[3456789]\d{9}$/, message: '手机号格式不正确', trigger: 'blur'}] } } }, methods: { removePhoneRule() { this.rules.phone = []; } } } </script> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k0933

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值