编号7 2021-11-30 15:06 采纳率: 0%
浏览 51

【element ui/vue】clearValidate('idCardNationalUrl'); 清除表单单项的验证不成功,结果把整个表单的验证都清除了

问题遇到的现象和发生背景

【element ui】图片上传控件,想要在上传之后能清除掉这单个的验证,但是结果是整个表单的验证都被清除了

问题相关代码,请勿粘贴截图
    <el-form-item label="身份证正面" prop="idCardNationalUrl" class="el-form-item2">

this.$nextTick(() => {
this.$refs.formEdit.clearValidate('idCardNationalUrl');
})

运行结果及报错内容

把整个表单的验证都清除了

我的解答思路和尝试过的方法
      this.$refs['formEdit'].clearValidate('idCardNationalUrl');
                this.$refs['formEdit'].clearValidate(['idCardNationalUrl']);

换不同的写法都试过了

我想要达到的结果

清除我传入的单个表单项验证

  • 写回答

1条回答 默认 最新

  • 观察蚂蚁的人 2022-03-23 05:06
    关注

    这个问题可以绕得开。
    核心思路:在传图成功的同时通过更新绑定值+局部清除验证,来清除上传组件的验证信息。
    关键步骤:
    1、将 绑定值 与 图片地址参数同步,减少后边的重复操作:将imageUrl与上传组件的对应model同步,可用computed同步这两个值;
    2、通过 绑定值+局部清除验证 解决上传控件的验证问题:在上传组件的handleAvatarSuccess函数中(on-success事件绑定的函数),更新this.imageUrl的值之后,需加代码消除验证,可用this.$refs.formRef.clearValidate("这里写上传组件所在的el-form-item的prop");
    3、提交表单成功以后,避免再次“被验证”:提交成功要重置表单,但此时表单绑定的model被清空,重置的瞬间会再次触发验证!所以要再次清除表单验证,而且需使用setTimeout来调用this.$refs.formRef..clearValidate(),以避免同时触发导致的清空失败。

    接下来的代码需要启动后端才能测出效果,Vue3+Node.js前后端分离,后端关键页面的代码也附上了。
    希望能够帮到你,如果有写得不清楚的地方可以追加提问哟~

    以下是前端代码:

    <template>
      <div class="formDiv">
        <span class="tit">表单示例</span>
        <el-form
          ref="formRef"
          :model="formM"
          :rules="formRule"
          label-position="left"
          hide-required-asterisk
          :status-icon=false
        >
          <el-form-item prop="name" label="名称" >
            <el-input v-model="formM.name" type="input" ></el-input>
          </el-form-item> 
    
          <el-form-item prop="pic" label="图片" >
            <el-upload
              class="avatar-uploader"
              :action="baseURL + '/formSubmit/picUL'"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="imageUrl" :src="imageUrl" class="avatar" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
          </el-form-item> 
    
          <el-form-item>
            <el-button type="primary" @click="submitForm()">提交</el-button>
          </el-form-item>
    
        </el-form>
      </div>
      <div class="hide">{{autoData}}</div>
    </template>
    
    <script>
    import { ref } from 'vue';
    import { ElMessage } from 'element-plus';
    import { Plus } from '@element-plus/icons-vue';
    
    export default {
      name: 'vq2',
      components:{Plus}, 
      data(){
        return{
          imageUrl: ref(''),
          formM: {name: "",pic:"",},
          formRule:{
            name: [
              {required: true, message: "名称不能为空", trigger: "change",},
              {min: 3, max: 8,
                validator(rule, value, callback) {
                  if (value.length < rule.min || value.length > rule.max) {
                    callback(new Error(`长度${rule.min}-${rule.max}位`));
                  } else {callback();}
              },},],
            pic:[{required: true, message: "上传图片不能为空", trigger: "change",},],},}
      },
      computed:{
        autoData(){
          this.formM.pic=this.imageUrl; //自动刷新上传控件的表单绑定值
          return this.imageUrl;
        }
      },
      methods:{    
        handleAvatarSuccess(res, file){
          switch (res.code) {
            case 111:
              this.imageUrl = URL.createObjectURL(file.raw);
              ElMessage.success('图片上传成功!')
              break;
            default:
              this.imageUrl = ref('');
              ElMessage.error('图片上传失败')
          } 
          this.$refs.formRef.clearValidate("pic"); //消除验证
        },
        beforeAvatarUpload(file){
          const limitSize=2;
          const isJPG = /jpeg|jpg|png/.test(file.type);
          const isLt = file.size / 1024 / 1024 < limitSize;
          !isJPG&&this.showAlertM('图片格式jpeg、jpg、png');
          !isLt&&this.showAlertM('图片大小超过'+limitSize+'M');
          return isJPG && isLt;
        },
        submitForm(){ //提交
          let form=this.$refs.formRef;
          form.validate(async (valid) => {
            if (valid) {
              let validationAx = await this.$axios({
                method: "POST",
                url: "/formSubmit/FormDataUL",
                data:this.formM,
              });
              switch (validationAx.data.code) {
                case 111:
                  this.imageUrl = ref('');
                  form.resetFields(); //提交成功,重置表单
                  window.setTimeout(()=>{form.clearValidate();},10);  //用定时器再清空一遍表单验证,是为了避免重置表单的同时触发验证导致验证清空失败的问题
                  ElMessage.success('提交成功!');
                  break;
                default:
                  ElMessage.error('提交失败');
              } 
            } else {
              ElMessage.error('验证未通过');
              return false
            }
          })
        },
      },
    }
    </script>
    <style lang="scss" scoped>
      .formDiv{
        position: relative;
        width: 500px;
    
        padding: 12px 0;
        
        margin: 24px auto ;
    
        border:1px solid rgba(125,125,125,0.1);
        border-radius: 7px;
    
        color:dodgerblue;
    
        display: flex;
        flex-flow: column nowrap;
        justify-content: space-evenly;
        align-items: center;
    
        &:hover{
          border-color:rgba(125,125,125,0.24);
          box-shadow: 1px 2px 1px rgba(125,125,125,0.01);
        }
      }
      .formDiv /deep/ .el-form {
        width: 100%;
    
        display: flex;
        flex-flow: column nowrap;
        justify-content: space-evenly;
        align-items: center;
      }
      .formDiv /deep/ .el-form-item{
        margin:0 0 24px;
        position: relative;
    
        &:nth-child(2){
          position: relative;
          left: -20px !important;
        }
        
      }
      .formDiv /deep/ .el-form-item__label{
        color: dodgerblue;
      }
      .tit{
        margin:0 0 12px;
      }
      .formDiv /deep/ .el-input__inner{
        width: 310px;
      }
    
      .avatar-uploader /deep/ .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: var(--el-transition-duration-fast);
        width: 178px;
        height: 178px;
      }
      .avatar-uploader /deep/ .el-upload:hover {
        border-color: var(--el-color-primary);
      }
      .avatar-uploader /deep/ .el-icon.avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        text-align: center;
      }
      .avatar{
        display: block;
        width: auto;
        height: 178px;
      }
      .el-alert{
        position:fixed;
        top:24px;
        margin: 20px 0 0;
        padding: 0 50px;
        width: auto;
        height:auto;
        overflow:visible;
    
        transition: all 0.7s ease-in-out;
      }
      .el-alert:first-child {
        margin: 0;
      }
    
      .hide{
        visibility: hidden;
      }
    </style>
    

    以下是后端代码,文件名为formSubmit.js,是路由的内容,需要将这个路由添加到router/index.js才能生效,具体方法我就不赘述了:

    const express= require("express");
    const router= express.Router();
    
    router.post("/picUL",async (req,res)=>{
        let reqData=req.body;
         res.send({
                    code:111,
                    message:"提交成功",
                    data:reqData,
        });
    });
    
    router.post("/FormDataUL",async (req,res)=>{
        let reqData=req.body;
         res.send({
                    code:111,
                    message:"提交成功",
                    data:reqData,
        });
    });
    
    module.exports=router;    
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 11月30日

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)