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

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

猜你喜欢

转载自blog.csdn.net/weixin_55846296/article/details/127094480
今日推荐