一、目标效果

        使用elementUI进行表单校验的时候,只能校验输入框、下拉选择列表等内容,就是没看到可以校验文件上传,这意味着你需要手动实现!目标效果如下:

        总而言之,就是这样的效果:(1) 不点击复选框,点击提交,可以通过校验;(2)点击复选框,不上传文件,校验不通过;(3)点击复选框,上传文件,提示字样消失,且校验通过;(4)点击复选框,显示必传的样式显示,不点击复选框,则不提示红点;

二、踩坑记录

        1、在form-item中需要填写prop,还需要在data中填写rules,并且prop的值与rules对应的规则相一致,不然起不到校验效果。

 

 

        2、自定义规则的时候,不写callback,则校验不生效

 

        3、此处会用到动态设置校验,很多人第一反应就是动态设置prop,即这样书写:

:prop=” 条件? '自己定义的rules下的规则' ? ' '  “

            3.1 这样的prop不生效,要写成:prop=” 条件? '自己定义的rules下的规则' ? 'empty'  “

                3.1.1 这样写还是有问题,万一以后自己在rules下定义的规则为empty呢,所以最佳做法不要动态设置prop,将prop写死,在规则校验器里面校验。

 

        4、el-upload的 action="https://jsonplaceholder.typicode.com/posts/" ,上传文件时会报跨域错误,且有时候报503错误。跨域的问题可以通过谷歌浏览器插件 

Allow CORS: Access-Control-Allow-Origin0.1.5  得到解决;其实在真实项目中,action后面跟的是后端的地址,这两个问题都自然迎刃而解。

 

        5、红点的生成采用动态绑定类名实现:

:class="条件?’is-required‘ :’ ‘ "

 

        6、通过 this.$refs.refName.clearValidate(prop值) 去清空校验提示字样

三、代码实现

<template>
  <div id="app">
    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px">
      <el-form-item label="活动名称:" :class="showFlag ? 'is-required' : ''" prop="file">
        <el-upload action="https://jsonplaceholder.typicode.com/posts/" :on-remove="handleRemove"
          :on-success="uploadSuccess">
          <el-button size="small" type="primary">点击上传</el-button>
        </el-upload>
      </el-form-item>
      <el-form-item label="必上传文件:">
        <input type="checkbox" v-model="showFlag" @change="handleCheckBoxChange" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">提交</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    // 文件上传校验规则
    const fileMustUpload = (rule, value, callback) => {
      if (this.showFlag && this.file == null) {
        // 未上传文件
        callback("请上传文件");
      }
      callback();
    }
    
    return {
      showFlag: false,    //判断红点是否显示,与复选框的值绑定在一起
      ruleForm: {
        file: null    //接受文件值
      },
      rules: {
        file: [
            //自定义校验器
          { validator: fileMustUpload, trigger: 'change' }
        ]
      }
    }
  },
  methods: {
    // 文件移除事件监听
    handleRemove() {
      this.file = null;
    },

    // 提交
    onSubmit() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          alert('上传成功!');
        }
      });
    },

    // 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    uploadSuccess(file) {
      this.clearFileUploadValidate();
      this.file = file
    },

    // 清空文件上传校验 
    clearFileUploadValidate() {
      this.$refs.ruleForm.clearValidate('file');
    },

    // 监听复选框值的变化
    handleCheckBoxChange(event) {
      // 复选框的值绑定给showFlag,并用它来控制红点必填样式
      this.showFlag = event.target.checked;
      if (!this.showFlag) {
        this.clearFileUploadValidate();
      }
    }
  },

}
</script>

<style>
.el-form {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

#app {
  height: 100%;
}
</style>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐