V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tlerbao
V2EX  ›  Vue.js

前端小哥进 Element UI 的上传组件怎么写表单验证

  •  
  •   tlerbao · 2021-09-28 19:39:17 +08:00 · 2527 次点击
    这是一个创建于 1155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    就算选择了文件,提交的时候还是表单验证不通过,我也是醉了。这个 upload 的组件的表单验证具体要怎么写呢,请各位指教。

    rules 也对 prop 也都对,upload 需要什么特殊设置吗?

    https://cdn.learnku.com/uploads/images/202109/28/86273/xIrsfTAQlR.jpg!large

    // html
        <el-form :ref="formImportName" :model="formImportData" :rules="importRules" >
            <el-form-item label="导入文件" :label-width="formLabelWidth" prop="select_file">
              <el-upload
                ref="upload"
                accept=".xlsx,.xls,.csv"
                :data="formImportData"
                :action="action"
                :on-success="handleSuccess"
                :limit="1"
                :headers="headers"
                :auto-upload="false">
                <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
                <div slot="tip" class="el-upload__tip">只能上传.xlsx/.xls/.csv 文件</div>
              </el-upload>
            </el-form-item>
          </el-form>
    
    // 验证规则,rule 名字 prop 都没错
    importRules: {
      select_file: [
         { required: true, message: '请选择文件', trigger: 'change' }
       ]},
     }
    
    // 提交的代码
    handleSubmitImport() {
      this.$refs[this.formImportName].validate((valid) => {
      if (valid) {
          this.$refs.upload.submit()
         } else {
              return false
          }
     })},
    
    
    
    
    8 条回复    2021-09-29 14:45:01 +08:00
    heyjei
        1
    heyjei  
       2021-09-28 19:46:52 +08:00
    前后端都是我一个人做的时候,前端就懒的做校验了,因为不管怎么样,后端还要再校验一遍
    hiro0729
        2
    hiro0729  
       2021-09-28 20:09:14 +08:00
    <el-form-item label="图片" prop="imgUrl">
    <Upload
    :file-list.sync="form.imgUrl"
    />
    <div>图片建议大小:680X300</div>
    </el-form-item>

    写个组件包裹一下 el-upload,然后关键是 :file-list.sync 会改变 form.imgUrl,不然你的代码里的 formImportData.select_file 并不会改变

    Upload 组件内:
    computed: {
    currFileList: {
    set(val) {
    this.$emit(
    'update:fileList',
    this.fileListIsString ? (val && val[0]) || '' : val.map(item => item)
    );
    }
    },
    }
    methods: {
    handleFileChange(file) {
    this.loading = true;
    console.log(file)
    if (file.response) {
    if (file.response.code === '10000') {
    let imgUrl = file.response.data.imgUrl;
    if (this.fileListIsString) {

    this.currFileList = [imgUrl];
    } else {
    this.currFileList = [...this.currFileList, imgUrl];
    }
    this.loading = false;
    this.$emit('suceess');
    } else {
    this.loading = false;
    this.$message.error('提交失败!');
    }
    }
    if (file.status === 'fail') {
    this.loading = false;
    this.$message.error('提交失败!');
    }
    },
    learningman
        3
    learningman  
       2021-09-28 20:20:23 +08:00
    @heyjei #1 前端校验是为了给出用户友好的提示,后端是为了安全,不能算一回事
    Biwood
        4
    Biwood  
       2021-09-28 20:37:37 +08:00
    印象中 element-ui 的表单校验只是对数据进行检测而已,你只要确保 formImportData.select_file 的值没问题,校验就能通过,跟 el-uploiad 没关系,他只是执行上传操作而已,上传成功后返回的文件 id 等数据还需要你手动复制给 formImportData.select_file
    tlerbao
        5
    tlerbao  
    OP
       2021-09-29 09:42:44 +08:00
    @Biwood 经过我测试,upload 组件不像其他的表单项 比如 input 失去焦点 change 什么的就会触发验证了,既是选择文件后也不会触发验证,this.$refs.form.validate.. 才会验证,这是其一,其二,就算给 upload 组件 v-model 绑定 formImportData.select_file,也没用 选文件后 this.$refs.form.validate 还是验证不通过,最后我目前是在 upload 的 on-change 里 给 formImportData.select_file 赋值,然后才会验证通过。
    Biwood
        6
    Biwood  
       2021-09-29 12:03:19 +08:00 via iPhone
    @tlerbao
    el-upload 因为是异步操作,而且无法对应到 html 里面的常规输入元素,所以跟 el-input 表现不一样是很正常的,可以看官方文档,el-upload 并没有 value/v-modle 属性,使用逻辑跟别的表单元素确实不一样。
    https://element.eleme.cn/#/zh-CN/component/upload%23attribute

    我上面想强调的是 el-form 的运作原理。你最后的写法没问题,其实我更推荐你在上传成功的回调里面赋值,更准确一些。像我上面说的 validate 方法只是触发了纯数据检测,就算没有 el-input 或者 el-upload,只要保留 el-form-item,照样能正常 validate,v-model 只是方便自动更新表单值,不是必须的,手动更新也一样。
    Flands
        7
    Flands  
       2021-09-29 14:18:15 +08:00
    我都是加个 input v-show=false,然后通过这个 input 对值进行校验
    tlerbao
        8
    tlerbao  
    OP
       2021-09-29 14:45:01 +08:00
    @Biwood 如果用户进页面就触发了 this.$refs.form.validate,验证没通过,这时候就算选了文件也通过不了,所以在 on-success 您说的上传成功后再赋值不行,所以在 on-change 选文件后就赋值,这时候验证就可以通过了,
    ```
    handleChange(file, fileList) {
    this.formImportData.select_file = file
    // 选择文件后单独对上传组件进行重新验证,已消除页面上已经存在的错误提示
    this.$refs[this.formImportName].validateField('select_file')
    },
    ```

    @Flands 确实是个办法哈,我也想到了,但是这是我最后选择,因为我是以为我菜,没找到 upload 写表单验证的正确姿势,所以一直找办法。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5262 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:36 · PVG 17:36 · LAX 01:36 · JFK 04:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.