首页 > 技术文章 > element的多文件上传

hubufen 2020-04-07 22:52 原文

项目需求:

  • 可上传多个文件
  • 可删除
  • 文件过大时用户输入可上传至其他网站,并将文件名和地址上传至本网站

问题点:

  • 大文件用户输入内容无法合并到已上传文件的列表进行展示
  • 上传多个大文件地址时前面已上传的大文件会被改变
  • 无法取消弹窗的代码校验

原因和解决方案

  • 大文件信息填写的之后可以将内容push到fileList, 并将值赋值给对应字段
  • 将对象push到数组, 是浅拷贝, 再次对对象进行赋值时, 数组中push的元素会被改变, 需要将浅拷贝改为深拷贝, 例如: push(JSON.parse(JSON.stringify(this.form)))
  • 我原本是想在弹窗出现时取消校验, 但是此时弹窗的DOM还未创建完成(可能是这个原因), 无法获取Dom, 会报错. 可以在点击弹窗的确定, 数据校验成功之后取消校验

所有原因及解决方案都在代码中有备注

element组件代码

<el-upload
          class="upload-demo"
          :action="actionUrl"
          :on-success="handleAvatarSuccess2"
          :before-upload="beforeAvatarUpload2"
          multiple
          :limit="5"
          :on-exceed="handleExceed"
          :before-remove="beforeRemove"
          :on-remove="handleRemove"
          :file-list="fileList"
        >
          <el-button size="small" type="primary">点击上传</el-button>
          <div slot="tip" class="el-upload__tip">
<!--            <p v-for="(itm, idx) of formDate.appendixSaveRequests" :key="idx">{{ itm.fileName }}</p>-->
          </div>
        </el-upload>

    <!--     上传大文件附件时的弹窗-->
    <el-dialog title="提示" :visible.sync="dialogFormVisible">
      <p class="i-info">
        <!--        <i class="el-icon-warning"></i>-->
        如果您需要上传的附件过大,可上传至网盘,在此留下网盘地址</p>
      <el-form :model="form" :rules="formRule" ref="form">
        <el-form-item label="附件名称" prop="fileName" :label-width="formLabelWidth">
          <el-input v-model="form.fileName" placeholder="请输入附件名称" autocomplete="off" />
        </el-form-item>
        <el-form-item label="附件地址" prop="fileUrl" :label-width="formLabelWidth">
          <el-input v-model="form.fileUrl" placeholder="例:http://***.com" autocomplete="off" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addBigFile">确 定</el-button>
      </div>
    </el-dialog>
// js部分
data () {
    return {
      dialogFormVisible: false,
      form: { // 大文件输入的名称和地址
        fileName: '',
        fileUrl: '',
      },
      fileList: [],
    }
},
methods: {
    // 添加大文件
    addBigFile() {
      this.$refs.form.validate(valid => {
        // 验证fileUrl地址和必填项非恐校验
        var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/;
        var re=new RegExp(strRegex);
        if (valid && re.test(this.form.fileUrl)) {
          this.dialogFormVisible = false
          this.form.name = this.form.fileName
        // this.form和this.fileList里的item都为对象类型, push相当于浅拷贝, 再次添加时this.form的值改变, 导致this.fileList里的值重复, 所以需要用深拷贝代替浅拷贝
          let form = JSON.parse(JSON.stringify(this.form))

            // 点击弹窗的确定时将弹窗中的内容push到fileList, 注意: push的字段名称要和fileList原本的字段名称一致
          this.fileList.push(form)
          this.resetForm('form')
        } else {
          this.$message.error('请输入正确的附件地址')
        }
      })
    },
    // 上传之前
    beforeAvatarUpload2(file) {
      const sizeFlag = file.size / 1024 / 1024 < 10
      if (!sizeFlag) {
        console.log(this.fileList, '=======')
        this.dialogFormVisible = true
        this.form.fileName = ''
        this.form.fileUrl = ''
        this.form.isThirdpartyStorage = true
      }
      return sizeFlag
    },
    // 上传成功
    handleAvatarSuccess2(res, row) {
      // console.log(res, row)
      if (res.code === 0) {
        // 下面为项目中上传附件的字段, 可忽略
        this.formDate.appendixSaveRequests.push({
          fileName: row.name,
          name: row.name,
          fileUrl: res.data.url,
          isThirdpartyStorage: false
        })
      }
    },
    // 已删除
    handleRemove(file, fileList) {
      console.log('this.fileList=111111==')
       // 编辑页面删除时要将后端返回的对应的字段内容删除
      this.formDate.appendixSaveRequests.map((item, index) => {
        if(item.uid === file.uid) {
          this.formDate.appendixSaveRequests.splice(index, 1)
        }
      })
    },
    // 达到限制数量
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件`)
    },
    // 删除之前
    beforeRemove(file, fileList) {
      // return this.$confirm(`确定移除 ${file.name}?`)
    }

}

推荐阅读