element的多文件上传

项目需求:

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

问题点:

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

原因和解决方案

  • 大文件信息填写的之后可以将内容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}?`)      }    }