• 【VUE的Form表单】使用v-if切换控件时,表单校验不生效


    背景

    这几天在开发管理端表单,有一个有效期限类型是否固定期限的单选按钮,对应控制切换有效期限的日期范围选择期限说明,最后的表单如下:
    在这里插入图片描述
    在这里插入图片描述

    两个都是必填,点击提交校验都要生效

    原始代码

    • 表单部分代码
    <a-form-model ref="form" :model="mdl">
      <a-row>
        
        <a-col :span="12">
          <a-form-model-item
            label="有效期限类型"
            prop="expirationType"
            :rules="{ required: true, message: '请输入有效期限类型', trigger: ['blur', 'change'] }"
          >
            <a-radio-group
              v-for="item in expirationTypeList"
              :key="item.value"
              v-model="mdl.expirationType"
              :disabled="false"
            >
              <a-radio :value="item.value">
                {{ item.name }}
              a-radio>
            a-radio-group>
          a-form-model-item>
        a-col>
        
        <a-col :span="12">
          <a-form-model-item
            label="有效期限"
            v-if="mdl.expirationType != 'WITHOUT'"
            :rules="{ required: true, message: '请输入有效期限.', trigger: ['blur', 'change'] }"
          >
            <a-form-model-item
              :rules="{ required: true, message: '请输入有效期限开始时间', trigger: ['blur', 'change'] }"
              prop="expirationStartTime"
              :style="{ display: 'inline-block', width: 'calc(50% - 12px)', marginBottom: '0px' }"
            >
              <a-date-picker
                :disabled-date="(start) => DateUtil.validate(start, mdl.expirationEndTime)"
                placeholder="开始时间"
                v-model="mdl.expirationStartTime"
                format="YYYY-MM-DD"
                :disabled="false"
              />
            a-form-model-item>
            <span :style="{ display: 'inline-block', width: '24px', textAlign: 'center' }">span>
            <a-form-model-item
              :rules="{ required: true, message: '请输入有效期限结束时间', trigger: ['blur', 'change'] }"
              prop="expirationEndTime"
              :style="{ display: 'inline-block', width: 'calc(50% - 12px)', marginBottom: '0px' }"
            >
              <a-date-picker
                :disabled-date="(end) => DateUtil.validate(mdl.expirationStartTime, end)"
                placeholder="结束时间"
                v-model="mdl.expirationEndTime"
                format="YYYY-MM-DD"
                :disabled="false"
              />
            a-form-model-item>
          a-form-model-item>
          <a-form-model-item
            v-if="mdl.expirationType == 'WITHOUT'"
            label="期限说明"
            prop="expirationExplain"
            :rules="{ required: true, message: '请输入期限说明.', trigger: ['blur', 'change'] }"
          >
            <a-input
              placeholder="请输入期限说明"
              v-model="mdl.expirationExplain"
              :maxLength="50"
              :disabled="false"
            />
          a-form-model-item>
        a-col>
      a-row>
    a-form-model>
    
    • 最后提交保存部分代码(这部分代码最后是不需要动的)
    save(){
      // 最后点击提交时会对表单整体做一次校验
      this.$refs.form.validate((res, object) => {
        if (!res) {
        	// 未通过校验:给出整体的提示
          this_.$message.error('请根据提示信息补全提交的内容信息')
          // 关闭提交,重新填写数据
          ...
        } else {
          // 校验通过,正常调接口保存数据
          ...
        }
      })
    }
    

    上述代码出现的问题

    我在切换 有效期限类型之后,点击提交,表单未对其添加校验,没有填写数据必填校验也通过了,最后尝试了v-show也还是不行,发现他的校验一直存在,即时没显示该控件

    原因:

    【1】使用 v-if:ant
    design在对form表单中带有prop属性的子组件进行校验规则绑定时,是在vue声明周期mounted完成的。而v-if用来切换的元素是会被销毁的,导致了v-if内的表单项,由于在mounted时期没有进行渲染,所以规则也没有绑定上,因此初始化时不符合显示条件的不会生成规则,导致后面切换条件,显示的输入框的校验不会生效
    【2】使用 v-show初始化时会生成所有的规则,即使隐藏了也会进行规则校验

    解决方案:

    给设置 v-if 的元素加上 key 值,如下所示:

    <a-row>
        //
        <a-col :span="12">
          <a-form-model-item
            label="有效期限类型"
            prop="expirationType"
            :rules="{ required: true, message: '请输入有效期限类型', trigger: ['blur', 'change'] }"
          >
            <a-radio-group v-model="mdl.expirationType" @change="expirationTypeChange">
              <a-radio v-for="item in expirationTypeList" :key="item.value" :value="item.value">
                {{ item.name }}
              a-radio>
            a-radio-group>
          a-form-model-item>
        a-col>
        
        <a-col :span="12">
          <a-form-model-item
            label="有效期限"
            v-if="mdl.expirationType != 'WITHOUT'"
            :rules="{ required: true, message: '', trigger: ['blur', 'change'] }"
            style="margin-bottom: 0px"
          >
            <a-form-model-item
              :rules="{ required: true, message: '请输入有效期限开始时间', trigger: ['blur', 'change'] }"
              prop="expirationStartTime"
              key="expirationStartTime"
              :style="{ display: 'inline-block', width: 'calc(50% - 12px)' }"
            >
              <a-date-picker
                :disabled-date="(start) => DateUtil.validate(start, mdl.expirationEndTime)"
                placeholder="开始时间"
                v-model="mdl.expirationStartTime"
                :format="dateFormat"
                :valueFormat="dateFormat"
                :disabled="false"
              />
            a-form-model-item>
            <span :style="{ display: 'inline-block', width: '24px', textAlign: 'center' }">span>
            <a-form-model-item
              :rules="{ required: true, message: '请输入有效期限结束时间', trigger: ['blur', 'change'] }"
              prop="expirationEndTime"
              key="expirationEndTime"
              :style="{ display: 'inline-block', width: 'calc(50% - 12px)' }"
            >
              <a-date-picker
                :disabled-date="(end) => DateUtil.validate(mdl.expirationStartTime, end)"
                placeholder="结束时间"
                v-model="mdl.expirationEndTime"
                :format="dateFormat"
                :valueFormat="dateFormat"
                :disabled="false"
              />
            a-form-model-item>
          a-form-model-item>
          <a-form-model-item
            v-if="mdl.expirationType == 'WITHOUT'"
            label="期限说明"
            prop="expirationExplain"
            key="expirationExplain"
            :rules="{ required: true, message: '请输入期限说明.', trigger: ['blur', 'change'] }"
          >
            <a-input
              placeholder="请输入期限说明"
              v-model="mdl.expirationExplain"
              :maxLength="50"
              :disabled="false"
            />
          a-form-model-item>
        a-col>
      a-row>
    

    最后呢,还添加了一个切换有效期限类型, 有效期限期限说明 数据清空的功能,我在网上查了,在控件(例如 a-input)上绑定key值v-if切换的时候,对应的数据会清空,但是呢,我们上边为了表单校验在a-form-model-item组件上绑定了key值,现在如果再在控件上去绑定key,v-if切换之后,控件上会无法填写数据,所以只能利用普通的js手动去切换清空数据:
    利用 a-radio-group的change属性API,代码如下:

    // 期限类型切换
    expirationTypeChange() {
      this.qualification.expirationStartTime ? (this.qualification.expirationStartTime = null) : ''
      this.qualification.expirationEndTime ? (this.qualification.expirationEndTime = null) : ''
      this.qualification.expirationExplain ? (this.qualification.expirationExplain = null) : ''
    },
    

    最后总结

    通过这次各种查看其他文章,我发现 key值 在vue中的作用挺大的,之后我也会整理出一篇比较全面的博客出来,各位敬请期待哦!!!

    还有,对于上面的问题,各位如果有更好的办法,欢迎评论区指导哦!

  • 相关阅读:
    Vue的生命周期的详解
    【leetcode】【剑指offer Ⅱ】028. 展平多级双向链表
    建造者模式
    深度解读昇腾CANN多流并行技术,提高硬件资源利用率
    论坛介绍 | COSCon'23 开源治理(G)
    【数据库高级】Mysql窗口函数的使用和练习
    关于Android12安装apk出现-108异常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解决方法
    什么是泛型?Java基础之泛型详细知识点总结
    计算机网络【CN】介质访问控制
    『现学现忘』Git基础 — 17、Commit对象
  • 原文地址:https://blog.csdn.net/weixin_55846296/article/details/127094480