关于vue+element多附件上传问题

element ui upload组件的多附件上传是循环调用上传接口的,在每次on-change 改变后调用后端接口交互

这样的话就会导致后台接口容易出错

想要点一下就可以上传多个附件的问题(最后也是实现了,但是问题比较多)

1.需要指定请求内容类型和token

不指定请求类型的话好像会默认转换为这个最好加上

 const config = { headers: { 'Content-Type': 'multipart/form-data',
          "Authorization": "Bearer " + getToken()}}

2.java程序接收使用(这俩种都可以)

@RequestParam("file") MultipartFile[] file

@RequestParam("file") List<MultipartFile> file

3.需要添加

 :on-change="handleChangeFile"


 handleChangeFile(file, fileList) {
      this.upload.fileList = fileList.slice(-4);

       //这个-4取决于最大附件上传个数    
       //因为是默认从后往前取数据  
       /*fileList.slice(-4):介绍
1. 方法介绍 : blob.slice(); 属于Blob对象的一个方法,而File对象是继承Blob对象的,因此File对象也含有slice方法
2. 参数介绍 : blob.slice(startByte,endByte); 这里需要注意它的参数,第一个参数startByte表示文件起始读取Byte字节,第二个参数则是结束读取字节。这里重点注意一下第二个参数,一开始我以为它是读取的长度,因为是在阅读《javascript高级程序设计》时它的例子介绍用length作为形参。结果我在进行文件分割上传的时候,一直获取不到第二次请求后的数据。
3.返回值 : newBlob = blob.slice(startByte,endByte); 它返回的仍然是一个Blob类型*/

    },

 (如果不添加会出现报错)提示成功但是没数据

参数也没有附件

java后台报错:Required request part 'file' is not present

(出现这个报错,一定要查看是不是上传的文件为空)

 4.完整案例

vue前台

<template>
  <div class="dashboard-editor-container">
    <el-upload
      ref="upload"
      :limit="upload.fileLimit"
      class="upload-demo"
      accept=""
      multiple
      :action="upload.url"
      :headers="upload.headers"
      :before-upload="beforeUpload"
      :file-list="fileList"
      :on-exceed="handleExceed"
      :on-change="handleChangeFile"
      :auto-upload="false">
      <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
      <el-button style="margin-left: 10px;" size="small" type="success" :loading="upload.isUploading" @click="submitUpload">上传到服务器</el-button>
    </el-upload>


  </div>
</template>

<script>
  import {getToken} from '@/utils/auth';
  import axios from 'axios'
  export default {
    name: 'Index',
    components: {

    },
    data() {
      return {
        upload: {
          // 是否禁用上传
          isUploading: false,
          // 设置上传的请求头部
          headers: { Authorization: "Bearer " + getToken() },
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + "/common1/uploadFile",//单附件上传
          fileList: [],
          // 允许的文件类型
          fileType: [ "pdf", "doc", "docx", "xls", "xlsx","txt","png","jpg", "bmp", "jpeg"],
          fileLimit:4
        },
      }
    },
    methods: {
      handleChangeFile(file, fileList) {
        this.upload.fileList = fileList.slice(-4);//-4为附件最大上传数
      },
      //上传文件之前
      beforeUpload(file){
        if (file.type != "" || file.type != null || file.type != undefined){
          //截取文件的后缀,判断文件类型
          const FileExt = file.name.replace(/.+\./, "").toLowerCase();
          //计算文件的大小
          const isLt100M = file.size / 1024 / 1024 < 100; //这里做文件大小限制
          //如果大于100M
          if (!isLt100M) {
            this.$modal.msgError("上传文件大小不能超过 50MB!");
            return false;
          }
          //如果文件类型不在允许上传的范围内
          if(this.upload.fileType.includes(FileExt)){
            return true;
          }
          else {
            this.$modal.msgError("上传文件格式不正确!");
            return false;
          }
        }
      },
      //超出文件个数的回调
      handleExceed(){
        this.$modal.msgError("超出最大上传文件数量的限制!");
      },
      // 文件提交处理
      async  submitUpload() {
        /*多附件上传*/
        let formData = new FormData();
        this.upload.fileList.forEach((item) => {
          formData.append("file", item.raw);
        });
        const config = { headers: {'Content-Type': 'multipart/form-data',
          "Authorization": "Bearer " + getToken()}}
        await  axios.post(process.env.VUE_APP_BASE_API+"/common1/uploadFiles",formData,config).then((res)=>{
          //成功处理
          this.$message.success("附件上传成功!");
        })
      },
    }
  }
</script>

java后台代码:

@RestController
@RequestMapping("/common1")
public class FileController{


    /**
     * 通用上传请求(多个)
     */
    @PostMapping("/uploadFiles")
    public AjaxResult uploadFiles(@RequestParam("file") MultipartFile[] file) throws Exception
    {

            if(file!=null && file.length>0){
                throw  new Exception("获取到的文件个数!"+file.length);
            }    
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Vue3和Spring Boot框架下的Element Plus附件上传和浏览功能,可以按照以下步骤进行操作: 1. 前端实现 在Vue3项目中,可以使用Element Plus提供的el-upload组件进行上传,同时利用axios发送上传请求,具体实现可以参考上一篇回答的代码示例。 在附件浏览的功能中,可以使用Element Plus提供的el-dialog组件和el-table组件,具体实现可以参考以下代码示例: ```vue <template> <div> <el-upload class="upload-demo" action="/api/upload" :on-success="handleSuccess" :file-list="fileList" multiple :limit="3" :on-exceed="handleExceed" :headers="headers"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> <el-button type="primary" @click="showDialog">查看附件</el-button> <el-dialog title="附件列表" :visible.sync="dialogVisible" width="50%"> <el-table :data="fileTableData" border> <el-table-column prop="filename" label="文件名"></el-table-column> <el-table-column prop="size" label="文件大小"></el-table-column> <el-table-column label="操作"> <template v-slot="scope"> <a :href="'/api/download/' + scope.row.filename">下载</a> </template> </el-table-column> </el-table> </el-dialog> </div> </template> <script> import axios from 'axios' export default { data() { return { fileList: [], headers: { Authorization: 'Bearer ' + localStorage.getItem('token'), }, dialogVisible: false, fileTableData: [], } }, methods: { handleSuccess(response, file, fileList) { this.$message.success('上传成功') this.fileList = fileList }, handleExceed(files, fileList) { this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${fileList.length + files.length} 个文件`) }, showDialog() { axios.get('/api/files') .then(response => { this.fileTableData = response.data this.dialogVisible = true }) .catch(error => { console.log(error) }) }, }, } </script> ``` 其中,`/api/files`接口可以用来获取已上传附件列表,返回的数据格式可以是一个包含文件名和文件大小的对象数组,例如: ```json [ { "filename": "file1.txt", "size": "123KB" }, { "filename": "file2.jpg", "size": "456KB" }, { "filename": "file3.pdf", "size": "789KB" } ] ``` 2. 后端实现 在Spring Boot项目中,可以使用Spring Boot提供的MultipartFile类来处理上传附件,同时可以使用Spring Boot提供的ResponseEntity类来处理下载请求,具体实现可以参考以下代码示例: ```java @RestController @RequestMapping("/api") public class FileController { private static final String UPLOAD_FOLDER = "uploads/"; @PostMapping("/upload") public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) { try { String filename = file.getOriginalFilename(); String filepath = Paths.get(UPLOAD_FOLDER, filename).toString(); Files.write(Paths.get(filepath), file.getBytes()); return ResponseEntity.ok().build(); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @GetMapping("/files") public ResponseEntity<List<FileMetadata>> getFiles() { List<FileMetadata> files = new ArrayList<>(); File uploadFolder = new File(UPLOAD_FOLDER); if (uploadFolder.exists()) { File[] fileList = uploadFolder.listFiles(); if (fileList != null && fileList.length > 0) { for (File file : fileList) { FileMetadata metadata = new FileMetadata(file.getName(), humanReadableByteCount(file.length())); files.add(metadata); } } } return ResponseEntity.ok(files); } @GetMapping("/download/{filename:.+}") public ResponseEntity<Resource> downloadFile(@PathVariable String filename) { Path filepath = Paths.get(UPLOAD_FOLDER, filename); Resource resource; try { resource = new UrlResource(filepath.toUri()); } catch (MalformedURLException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } if (resource.exists() && resource.isReadable()) { HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename); return ResponseEntity.ok().headers(headers).body(resource); } else { return ResponseEntity.notFound().build(); } } private static String humanReadableByteCount(long bytes) { if (bytes < 1024) { return bytes + "B"; } int exp = (int) (Math.log(bytes) / Math.log(1024)); String pre = "KMGTPE".charAt(exp - 1) + "i"; return String.format("%.1f%sB", bytes / Math.pow(1024, exp), pre); } private static class FileMetadata { private final String filename; private final String size; public FileMetadata(String filename, String size) { this.filename = filename; this.size = size; } public String getFilename() { return filename; } public String getSize() { return size; } } } ``` 其中,`/api/download/{filename}`接口可以用来处理下载请求,返回的是一个附件文件流,可以在前端实现中通过a标签的href属性来实现下载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值