el-upload上传图片图片、el-load默认图片重新上传、el-upload初始化图片、el-upload编辑时回显图片

  • 问题
    我用el-upload上传图片,再上一篇文章已经解决了,el-upload上传图片给SpringBoot后端,但是又发现了新的问题,果然bug是一个个的冒出来的。新的问题是el-upload编辑时回显图片的保存
    • 问题描述:回显图片需要将默认的 file-list设置为data中的属性,以设置默认值。如下,设置为imgList
csharp 复制代码
 <el-upload
            action=""
            list-type="picture-card"
            multiple
            :on-change="handlChange"
            :file-list="imgList"
            :on-error="handleErr"
            ref="upload"
            :limit="10"
            accept=".jpg,.png,.jpeg"
            :on-exceed="handleMaxNum"

            :auto-upload="false">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url" alt=""
              >
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>

                <span

                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>

但是这样的自己设置的值,他的格式是这样的:

csharp 复制代码
this.imgList = this.imgList.map(url => ({
          url: url,
        })

与自己上传文件通过:file_list得到的内容不同 ,(也就是如果你有个添加图片的功能,有个编辑图片的功能,编辑功能你要设置初始值,但是他们的imgList不一样),有图为证

这会导致什么呢?首先,我们需要将imgList的文件转成FormData格式的文件 传给后端,通过获取file-ist,可以通过:on-change="handlChange"获取

csharp 复制代码
 handleChange(file, fileList) {
      this.imgList = fileList;
    },
  1. 如果你是添加图片 的功能的时候,他是没问题 的,可以直接使用
    formData.append('files', item.raw);转成FormData的类型。
  2. 但是如果你是要回显图片再保存 ,即编辑的功能,这个时候你要设置初始值,即用上面所说的方式设置。这种格式的的imgList,就不能直接使用 formData.append('files', item.raw);这种方式转成FormData,而要使用fetch的方式
  • 解决
    下面是解决的代码,可以先对imgList的url进行判断,因为自己上传的url开头是不带"blob"的 ,顺便说一下,因为fetch是异步的 ,所以要通过设置Promise,等fetch全部执行完再进行保存图片,否则FormData还是会为空
csharp 复制代码
this.imgList.forEach(item => {
    let url = item.url;
    if(url.startsWith("blob")){
      formData.append('files', item.raw);
    }
    else {
      let promise = fetch(url, {
          headers: new Headers({
            'Origin': location.origin
          }),
          mode: 'no-cors'
        }
      )
        .then(response => response.blob())
        .then(blob => {
          // 创建 URL 对象以便提取文件名

          let filename = url.split('/').pop();

          // 创建一个虚拟的 File 对象
          let file = new File([blob], filename, {type: 'image/bmp,image/jpeg,image/png,image/webp'});
          console.log(file)
          formData.append('files', file);

        })
        .catch(error => {
          console.error('Failed to fetch image:', error);
        });
      promises.push(promise);
    }
  });
  Promise.all(promises).then(() => {
  console.log("formdata", formData)

         let uri = "/" + newAttractionId
         saveImgs(uri, formData)
           .then(resPic => {
             if (resPic.data.success) {
               // this.$message({
               //   type:"success",
               //   message:resPic.data.msg
               // })
             } else {
               this.$message({
                 type: "info",
                 message: resPic.data.msg
               })
             }

           }).catch(err => {
           console.log("出错", err)
         })

整合主要代码如下

csharp 复制代码
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
  <el-dialog :title="title" :visible.sync="editFormVisible" width="35%" @click="closeDialog">
     <el-form-item label="图片" prop="imgList">
          <!--          :file-List可以填默认值-->
          <el-upload
            action=""
            list-type="picture-card"
            multiple
            :on-change="handleChange"
            :file-list="imgList"
            :on-error="handleErr"
            ref="upload"
            :limit="10"
            accept=".jpg,.png,.jpeg"
            :on-exceed="handleMaxNum"

            :auto-upload="false">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url" alt=""
              >
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>

                <span

                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>
        </el-form-item>
      </el-form>
      
data() {  

      imgList: [],
}
methods: {
handleRemove(file) {

      let arr = this.$refs.upload.uploadFiles
      console.log("arr是",arr)
      // 2.从pics数组中,找到图片对应的索引值
      let index = arr.indexOf(file)
      // 3.调用splice方法,移除图片信息
      arr.splice(index, 1)
      this.imgList=arr
      console.log(this.imgList)

    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleChange(file, fileList) {
      this.imgList = fileList;
    },
    handleMaxNum() {
      this.$message({
        type: "info",
        message: "最多选择10张图片"
      })
    },
// 编辑、增加页面保存方法
    subm**加粗样式**itForm(editData) {
      this.loading = true

      this.$refs[editData].validate(valid => {
          if (valid) {
            attractionSave(this.editForm)
              .then(res => {
                  this.editFormVisible = false

                  // console.log(res)
                  if (res.data.success) {

                    let newAttractionId = res.data.attractionId

                    //信息保存成功后,保存图片
                    if ( newAttractionId != '') {
                      let formData = new FormData(); // 用 FormData 存放上传文件

                      // 将图片转为 FormData 格式
                      let promises = [];
                      this.imgList.forEach(item => {
                        let url = item.url;
                        if(url.startsWith("blob")){
                          formData.append('files', item.raw);
                        }
                        else {
                          let promise = fetch(url, {
                              headers: new Headers({
                                'Origin': location.origin
                              }),
                              mode: 'no-cors'
                            }
                          )
                            .then(response => response.blob())
                            .then(blob => {
                              // 创建 URL 对象以便提取文件名

                              let filename = url.split('/').pop();

                              // 创建一个虚拟的 File 对象
                              let file = new File([blob], filename, {type: 'image/bmp,image/jpeg,image/png,image/webp'});
                              console.log(file)
                              formData.append('files', file);

                            })
                            .catch(error => {
                              console.error('Failed to fetch image:', error);
                            });
                          promises.push(promise);
                        }
                      });


                      Promise.all(promises).then(() => {
                        console.log("formdata", formData)

                        let uri = "/" + newAttractionId
                        saveImgs(uri, formData)
                          .then(resPic => {
                            if (resPic.data.success) {
                              // this.$message({
                              //   type:"success",
                              //   message:resPic.data.msg
                              // })
                            } else {
                              this.$message({
                                type: "info",
                                message: resPic.data.msg
                              })
                            }

                          }).catch(err => {
                          console.log("出错", err)
                        })
                      })
                    }


                    this.$message({
                      type: 'success',
                      message: res.data.msg
                    })
                  } else {
                    this.$message({
                      type: 'info',
                      message: res.data.msg
                    })
                  }

                }
              )
              .catch(err => {
                this.editFormVisible = false
                this.loading = false
                this.$message.error('保存失败,请稍后再试!')
                console.log(err)

                return false
              })
            var that = this
            setTimeout(function () {
              that.loading = false;
              that.getData()
            }, 1000)

          } else {
            this.loading = false
            return false
          }
        }
      )

    },
     //显示编辑界面
    handleEdit: function (index, row) {

      this.editFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改';
        this.imgList=row.imgList
        this.imgList = this.imgList.map(url => ({
          url: url,
        }));
        console.log("list", this.imgList)

      } 
    }
  </el-dialog>

同时,附上SpringBoot业务层代码

csharp 复制代码
  @Override
    public ResJson savePicture(List<MultipartFile> files, String attractionLocationById) {
        ResJson resJson = new ResJson();
        // 获取文件夹中所有文件的列表
        File file1 = new File(attractionLocationById);
        File[] folderFiles = file1.listFiles();

         // 创建一个 HashSet,用于存储上传文件的名称
        Set<String> uploadedFileNames = new HashSet<>();
        if(files==null) {
            for (File folderFile : folderFiles) {
                if (folderFile.delete()) {

                    System.out.println("删除文件: " + folderFile.getName() + " 成功");
                } else {
                    System.out.println("删除文件: " + folderFile.getName() + " 失败");
                }
            }
            file1.delete();
            return null;
        }
        for (MultipartFile file : files) {
            uploadedFileNames.add(file.getOriginalFilename());
        }

        System.out.println("uploadedFileNames = " + uploadedFileNames);


        //删除图片,其实只要全部删除,再重新下载即可,考虑到图片数量可能多,就搞成判断了
        if(folderFiles!=null) {
            // 遍历文件夹中的文件
            for (File folderFile : folderFiles) {
                String folderFileName = folderFile.getName();
                // 如果文件夹中的文件不在上传的文件列表中,则删除该文件

                if (!uploadedFileNames.contains(folderFileName)) {
                    System.out.println(folderFileName);
                    if (folderFile.delete()) {

                        System.out.println("删除文件: " + folderFile.getName() + " 成功");
                    } else {
                        System.out.println("删除文件: " + folderFile.getName() + " 失败");
                    }
                }
                else{
                    uploadedFileNames.remove(folderFileName);
                }

            }
        }


        // 保存上传的文件
        for (MultipartFile file : files) {
            try {

                String originalFilename = file.getOriginalFilename();
                //如果已经有了,在上面的被移除了,只有在剩下的没被排除内的就下载
                if(uploadedFileNames.contains(originalFilename)) {
                    // 构建真实的文件路径
                    Path path = Paths.get(attractionLocationById + originalFilename);

                    // 确保目录路径存在
                    Files.createDirectories(path.getParent());
                    // 将上传文件保存到指定位置
                    file.transferTo(path);
                    System.out.println("图片保存成功");
                    System.out.println("保存+1");
                }
                resJson.setMsg("图片保存成功");
                resJson.setSuccess(true);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("上传失败");
                resJson.setMsg("图片保存失败");
                resJson.setSuccess(false);
            }

        }

        return resJson;
    }
相关推荐
sunshine6419 分钟前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻33 分钟前
Vue(四)
前端·javascript·vue.js
蜜獾云35 分钟前
npm淘宝镜像
前端·npm·node.js
dz88i835 分钟前
修改npm镜像源
前端·npm·node.js
Jiaberrr39 分钟前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook
东方隐侠安全团队-千里1 小时前
网安瞭望台第17期:Rockstar 2FA 故障催生 FlowerStorm 钓鱼即服务扩张现象剖析
网络·chrome·web安全
顾平安2 小时前
Promise/A+ 规范 - 中文版本
前端
聚名网2 小时前
域名和服务器是什么?域名和服务器是什么关系?
服务器·前端
桃园码工2 小时前
4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]
前端·html·gin·模板渲染
不是鱼2 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js