自定义el-upload 上传文件

本文讲述了作者在使用ElementPlus的el-upload组件时,如何实现文件分步选择和上传的过程,包括关闭自动上传、自定义http-request函数以及处理axios的Content-Type设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

        最近在做一个文件上传的功能,后端接口写好了、发现前端上传文件的页面不会写……(刚接触)然后我就找解决方案,后面找发现Element有个组件是<el-upload/>能直接上传文件。

        我就想直接用拿来改成自己想要的,花了很多时间去都改不好。网上找的好多教程都是有一定基础的人看的,不适合我这种小白。我照着他们的改是一点都改不出来效果。后面我终于摸索出来了,想着这么麻烦肯定要水一篇博客才行。

需求

        我先讲一下我的需求,你们需求不一样的可以不用看了,免得浪费时间。

        一个组件能上传文件,一个按钮选中文件,一个按钮提交。不是自动提交。如下图:

实现代码

 这是官方的api可以去看详细解释,但是太简洁了我基础比较差不太能看懂。下面是我摸索出来的结论,大家可以看一下不对的可以提出进行改正。

Upload 上传 | Element Plus

        默认的el-upload 有个参数action填的是你上传的后端地址,你想自定义上传函数的话你要用http-request是覆盖它,这样就能自定义函数了。但是actio还不能省你得空着在那。

        auto-upload是关闭自动上传的,你要实现一个按钮上传一个按钮提交就得关闭这个!

然后去写handleUpload函数。

el-upload ref="upload" :show-file-list="true"
      :auto-upload="false"
      :http-request="handleUpload" 
      action=" "
      :limit="1">
      <el-button type="primary">选择文件</el-button>
      <template #tip>
        <div class="el-upload__tip">
          只能上传xlsx文件
        </div>
      </template>
    </el-upload>
    <el-button type="primary" style="margin-left: 50px;" @click='handleAction'>批量导入</el-button>

         handleUpload函数 就是绑定在el-upload上的http-request属性,这个名字可以你随便取,大概解释一下就是http-request他会给你一个参数,那个参数就是你选中的那个文件的参数。下面的data.file就是那个文件的具体参数。你们可以console.log去看看它是一个对象来着的,然后创建一个FormData,将那个file赋值给formData(我不太懂这是什么意思)我是在这看到这样赋值的 我照着做就能成功了。

        在下面就是一些axios请求后端接口了,url换成你们的就行,后面接的就是包含上传文件信息的formData了,最重要的是你请求的控制头一定要是  'Content-Type': 'multipart/form-data' 不然是传不了文件的,后端接口会报file null的错误。

 handleUpload(data) {
            console.log(data)
            const file = data.file;
            console.log(file)
            const formData = new FormData();
            formData.append('file', file);

            axios.post('http://localhost:9090/user/excelUpload', formData, {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            }).then(res => {
                console.log(res)
                if (res.data.code === '200') {
                    this.$message({
                        type: "success",
                        message: "批量导入成功"
                    })
                } else {
                    this.$message({
                        type: "error",
                        message: res.data.msg
                    })
                }
                this.$refs.upload.clearFiles(); // 清除上传的文件列表
            })
        }

        说到我就很迷惑我自己用了axios封装了一个request里面定义了请求头,是json的。后面我在使用的vue文件去import使用的时候,需要覆盖它这个请求头,换成 'Content-Type': 'multipart/form-data' 嘛,它竟然是不生效的!请求还是全局设置里面的json,害得我找半天都找不到原因,一直怀疑是现在的代码是有问题的。希望有懂的大佬指点一下。

request.interceptors.request.use(config => {
    // 设置请求头
    config.headers['Content-Type'] = 'application/json;charset=utf-8';

    return config
}, error => {
    // 请求失败,返回错误信息
    return Promise.reject(error)
})


完整的代码

<template>
  <div style="margin: 30px; display: flex; justify-content: center;">
    <el-upload ref="upload" :show-file-list="true" :auto-upload="false" 
    :http-request="handleUpload" action=" "
      :limit="1">
      <el-button type="primary">选择文件</el-button>
      <template #tip>
        <div class="el-upload__tip">
          只能上传xlsx文件
        </div>
      </template>
    </el-upload>
    <el-button type="primary" style="margin-left: 50px;" @click='handleAction'>批量导入</el-button>
  </div>
</template>

<script>
import axios from 'axios';
export default {
  methods: {
    handleAction() {
      this.$refs.upload.submit();
    },
    // 自定义上传方法
    handleUpload(data) {
      console.log(data)
      const file = data.file;
      console.log(file)
      const formData = new FormData();
      formData.append('file', file);

      axios.post('http://localhost:9090/user/excelUpload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(res => {
        console.log(res)
        if (res.data.code === '200') {
          this.$message({
            type: "success",
            message: "批量导入成功"
          })
        } else {
          this.$message({
            type: "error",
            message: res.data.msg
          })
        }
        this.$refs.upload.clearFiles(); // 清除上传的文件列表
      })
    }
  }
}
</script>

### 自定义 Element UI `el-upload` 组件的文件列表回显样式 为了自定义 `el-upload` 文件列表回显样式的实现方式,可以采用多种方法来调整默认外观。一种常见的方式是通过覆盖 CSS 类名来自定义样式。 #### 方法一:使用内联样式或全局CSS重写类名 Element UI 的 `el-upload` 组件内部会为每一个上传成功的文件项生成特定结构的 HTML 元素,并赋予相应的 class 名字。可以通过这些已知的class名称来进行样式定制[^1]: ```css /* 修改整个文件列表容器 */ .el-upload-list { /* 定义自己的样式规则 */ } /* 针对单个文件项进行修改 */ .el-upload-list__item { border: 1px solid red; margin-bottom: 8px; } ``` 如果希望只针对某个具体的实例生效而不是全部页面上的所有上传控件,则可以在模板里给该组件加上唯一的 ref 或者额外的 wrapper div 并指定其 className 属性,在此基础之上编写更精确的选择器路径以达到局部作用域的效果。 #### 方法二:利用 scoped 样式表与深度选择符 当在一个 Vue文件组件 (SFC) 中工作时,推荐的做法是在 `<style>` 块中添加 `scoped` 关键词以及 `/deep/` 操作符(对于较新的版本可能需要用 `::v-deep` 替代)。这允许开发者安全地为目标元素设置样式而不影响其他部分[^2]: ```html <template> <!-- ... --> </template> <style lang="scss" scoped> .my-custom-uploader /deep/ .el-upload-list, .my-custom-uploader /deep/ .el-upload-list__item { // 这里的样式只会应用于此处声明的 my-custom-uploader 下面的 upload list 及 item 上 } </style> ``` 需要注意的是,随着不同框架和工具链的发展变化,某些情况下上述语法可能会有所差异;因此建议查阅最新文档确认最佳实践。 另外值得注意的一点是,除了简单的视觉效果外,还可以考虑结合 JavaScript 来动态改变样式属性或是响应用户的交互行为,比如点击事件触发后的高亮显示等复杂需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值