Loading

element-ui 中upload组件与表单组件的结合使用

背景

有的时候我们需要在表单中携带一些上传的附件传给服务器

搭建基本表单结构

<template>
  <div>
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="上传附件" prop="attachment" class="upload-item">
        <el-upload
          ref="upload"
          action=""
          :on-remove="handleRemove"
          :file-list="fileList"
          :auto-upload="false"
        >
          <el-button slot="trigger" size="small" type="primary"
            >选取文件</el-button
          >
          <div slot="tip" class="el-upload__tip">
            只能上传jpg/png文件,且不超过500kb
          </div>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
          >立即创建</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      ruleForm: {
        name: '',
        region: '',
        attachment: '',
      },
      rules: {
        name: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
        ],
        region: [
          { required: true, message: '请选择活动区域', trigger: 'change' },
        ],
        attachment: [
          { required: true, message: '请上传附件', trigger: 'blur' },
        ],
      },
      fileList: [],
    }
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!')
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    },
    handleRemove(file, fileList) {
      console.log(file, fileList)
    },
  },
}
</script>

<style scoped>

</style>

问题1:upload的label不垂直居中

添加如下样式即可解决。

.upload-item {
  display: flex;
}
/deep/ .upload-item .el-form-item__label {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: orange;
}
/deep/ .upload-item .el-form-item__content {
  margin-left: 0 !important;
}

效果如下:

问题2:文件已经上传,但是表单组件校验不通过

问题效果:

解决办法:使用表单组件中的自定义规则

data() {
    var validateAttachment = (rule, value, callback) => {
      if (value == '') {
        return callback(new Error('上传的附件不能为空'))
      } else {
        console.log('有上传附件')
        callback()
      }
    }
    return {
      ruleForm: {
        name: '',
        region: '',
        attachment: [],
      },
      rules: {
        name: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
        ],
        region: [
          { required: true, message: '请选择活动区域', trigger: 'change' },
        ],
        attachment: [{ validator: validateAttachment, trigger: 'change' }],
      },
    }

优化

需求一:上传文件后,当移除时提示"附件必填"错误的消息;
需求二:表单中存在多个上传文件,为某个指定的表单项做单独的设置

如何获取到对应的表单项?

<el-upload 
          :on-remove="
            (file, fileList) => {
              handleRemove('attachment', file, fileList)
            }
          "
          :file-list="ruleForm.attachment"
          :auto-upload="false"
          :on-change="
            (file, fileList) => {
              handleUploadChange('attachment', file, fileList)
            }
          "
        >

完整代码

<template>
  <div>
    {{ ruleForm }}
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item
        label="上传附件"
        prop="attachment"
        required
        class="upload-item"
      >
        <el-upload
          ref="upload"
          action=""
          :on-remove="
            (file, fileList) => {
              handleRemove('attachment', file, fileList)
            }
          "
          :file-list="ruleForm.attachment"
          :auto-upload="false"
          :on-change="
            (file, fileList) => {
              handleUploadChange('attachment', file, fileList)
            }
          "
        >
          <el-button slot="trigger" size="small" type="primary"
            >选取文件</el-button
          >
          <div slot="tip" class="el-upload__tip">
            只能上传jpg/png文件,且不超过500kb
          </div>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
          >立即创建</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    var validateAttachment = (rule, value, callback) => {
      if (value == '') {
        return callback(new Error('上传的附件不能为空'))
      } else {
        console.log('有上传附件')
        callback()
      }
    }
    return {
      ruleForm: {
        name: '',
        region: '',
        attachment: [],
      },
      rules: {
        name: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
        ],
        region: [
          { required: true, message: '请选择活动区域', trigger: 'change' },
        ],
        attachment: [{ validator: validateAttachment, trigger: 'change' }],
      },
    }
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!')
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    },
    handleRemove(field, file, fileList) {
      // console.log(file, fileList)
      this.ruleForm[field] = []
      this.$refs.ruleForm.validateField('attachment')
    },
    handleUploadChange(field, file, fileList) {
      this.ruleForm[field].push(file)
    },
  },
}
</script>

<style scoped>
/* 解决表单中嵌入上传组件时label不居中的问题 */
.upload-item {
  display: flex;
}
/deep/ .upload-item .el-form-item__label {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: orange;
}
/deep/ .upload-item .el-form-item__content {
  margin-left: 0 !important;
}
</style>

效果如下:

posted @ 2022-12-05 23:29  ^Mao^  阅读(1375)  评论(0编辑  收藏  举报