当前位置: 首页 > news >正文

【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>
    <!-- 9、有效期限 -->
    <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中的作用挺大的,之后我也会整理出一篇比较全面的博客出来,各位敬请期待哦!!!

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

相关文章:

  • EnumWindowsProc
  • SSL安全证书:免费的SSL证书申请渠道有哪些?
  • SQL语言---数据的查询
  • 建模杂谈系列162 APIFunc: 可靠的复杂函数开发3
  • nslookup命令的常见用法
  • 如果你也想在linux中删除指定行
  • 掩码和反掩码的使用场景
  • QT案例实战1 - 从零开始编写一个OCR工具软件 (3)创建项目
  • FFmpeg入门详解之68:FFmpeg4.3的开发环境搭建
  • CSS 单位解析
  • 【Windows无法修复问题】“启动修复”无法修复你的电脑解决方法
  • 短信验证码接口风险分析
  • SpringBoot 自定义注解异步记录复杂日志
  • 组件component二次开发属性暴露,跟渲染元素属性暴露类似,但主要是canvas画笔来绘制组件图形
  • 工作四年,分享50个让你代码更好的小建议
  • Babel配置的不完全指南
  • crontab执行失败的多种原因
  • ES学习笔记(12)--Symbol
  • js ES6 求数组的交集,并集,还有差集
  • leetcode388. Longest Absolute File Path
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • PHP的类修饰符与访问修饰符
  • 给github项目添加CI badge
  • 解析 Webpack中import、require、按需加载的执行过程
  • 如何优雅地使用 Sublime Text
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 通信类
  • 我建了一个叫Hello World的项目
  • 组复制官方翻译九、Group Replication Technical Details
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #《AI中文版》V3 第 1 章 概述
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (1)Android开发优化---------UI优化
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (4)(4.6) Triducer
  • (java)关于Thread的挂起和恢复
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (差分)胡桃爱原石
  • (三)c52学习之旅-点亮LED灯
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (一)插入排序
  • (转)Sublime Text3配置Lua运行环境
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .“空心村”成因分析及解决对策122344
  • .gitignore文件_Git:.gitignore
  • .java 9 找不到符号_java找不到符号
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET Standard 的管理策略
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 指南:抽象化实现的基类
  • .net生成的类,跨工程调用显示注释
  • /run/containerd/containerd.sock connect: connection refused