基于el-upload实现文件上传组件封装以及细节处理

写在前面

  • 本文技术栈基于Vue2+ElementUi+Axios+Less
  • 文件上传在日常开发中也是非常常见,本文会基于实际项目的需求从0到1手把手带你基于el-upload封装一个文件上传组件,同时介绍一些需要注意的细节

组件的一些功能功能点

  • 选取文件时自动上传文件,即auto-upload=true这也是默认值;特别指出这个属性也是因为当此属性设置为false时需要手动触发上传函数,逻辑与自动上传处理时存在差异
  • 下面栗子以图片上传为例,只允许上传一张,并且文件上传成功后展示图片文件的同时隐藏上传组件,在清空上传内容时再重新展示组件(因此这么做的话on-exceed函数也就不再需要了)
  • 需要上传文件的预览、删除以及数据回显,值得一提的是预览和删除功能逻辑组件已经内置了;但是预览我们需要考虑的是样式问题以及不同文件的预览,例如图片,音视频等等

例子准备

  • 根据上面的需求,先找到对应的组件demo栗子,如下:
  • 在这里插入图片描述

自定义参数以及钩子函数

  • 当然,除了原有栗子,想要实现上述功能点的话,还需要添加额外的钩子函数以及属性,例子如下,根据需要设置一些属性和钩子函数,用于处理逻辑
    在这里插入图片描述
  • 关键的上传钩子:文件上传前的格式校验,填充额外的请求参数;文件上传成功的钩子,能够拿到接口返回的参数
// 文件上传前的钩子
handleBeforeUpload(file) {
  // 获取文件后缀
   const suffix = file.name?.slice(file.name?.lastIndexOf('.') + 1)
   const reg = /jpe?g|png/i
   if (!reg.test(suffix)) {
     this.$message.warning('仅支持jpg、jpeg、png格式的图片!')
     return false
   }
   // 上传的额外参数,例如id,name等等,根据情况有需要的话添加
   this.fileListData.unitId = id;
   this.fileListData.name = name;
 }
// 文件上传成功,接受一个返回对象
 handleSuccess(response) {
    // TODO 根据返回的response对象,进行自己想要的操作,例如属性赋值等等
    this.$message.success('上传成功!')
  },

请求栗子

  • 根据上面的描述,以图片上传为例执行一个上传请求
  • 可以看到请求体的参数默认为FormData格式,file 属性对应的参数就是上传的文件内容,其他参数是根据需求咱们自己添加的,即上面提到的参数 data 绑定的对象
    在这里插入图片描述
  • 可以看到文件上传成功后,上传组件依旧存在,但是一开始说过这里文件限制上传一个,所以这里的处理是上传成功之后隐藏上传组件;而不是等用户上传第二个时提示他只能上传一个,从而浪费时间进行无意义的操作
  • 隐藏组件的话通过样式简单控制就行,需要注意的时需要用到属性透传(不建议使用全局样式或是通过!import等方式去处理,容易造成全局样式污染!!!),我这v2项目是用/deep/,例如v3用的就是:deep(),根据自己情况使用,样式代码如下:
<style lang="less" scoped>
.hideUpload /deep/ .el-upload--picture-card {
  display: none;
}
</style>
  • 组件通过 :class 动态绑定类名,也就是hideUpload;接着通过自定义isHideUplaod属性(它是一个布尔值)来控制类名样式是否应用
    在这里插入图片描述
  • 那么效果就会变成这样
    在这里插入图片描述

完整代码

  • 组件名字这里定义为 UploadPhotoFile
<template>
  <div>
    <el-upload
      class="upload-cover"
      drag
      list-type="picture-card"
      :class="{ hideUpload: isHideUplaod }"
      :action="uploadUrl"
      :limit="1"
      :file-list="fileList"
      :on-success="handleSuccess"
      :before-upload="handleBeforeUpload"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :data="otherReqParams"
    >
      <div class="up-tip" >
        <!-- <img src="@/assets/images/u897.png" alt=""> -->
        <div class="el-upload__text">
          <span>点击或将文件拖拽到这里上传</span>
        </div>
      </div>
      
      <div class="el-upload__tip" slot="tip">
        格式:支持jpg、jpeg、png;尺寸:750px*420px;限1M以内只可上传一张
      </div>
    </el-upload>
    <el-dialog :visible.sync="imgConfig.dialogVisible">
      <img width="100%" :src="imgConfig.dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
export default {
  props: {
    // 父组件传入的请求对象,用于请求参数赋值;
    // 或者通过 $emit('xxx', params)方式将参数返回给父组件
    reqParams: {
      type: Object,
      default: () => {}
    },
    // 数据回显
    fileList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      uploadUrl: "",//文件上传地址
      otherReqParams: {//额外的请求参数
        fileType: 1, 
        multipartFile: {}
      },
      imgConfig: { //文件与预览相关
        dialogVisible: false,
        dialogImageUrl: ''
      },
      isHideUplaod: false,//上传组件的显隐控制
    }
  },
  created() {
    this.uploadUrl = 'xxxx' //拿到文件上传地址
  },
  methods: {
    // 删除文件
    handleRemove() {
      this.isHideUplaod = false
    },
    // 文件预览
    handlePictureCardPreview(file) {
      this.imgConfig.dialogImageUrl = file.url;
      this.imgConfig.dialogVisible = true;
    },
    // 上传成功的操作
    handleSuccess(response) {
      this.isHideUplaod = true
      this.$message.success('上传成功!')
    },
    handleBeforeUpload(file) {
      const suffix = file.name?.slice(file.name?.lastIndexOf('.') + 1)
      const reg = /jpe?g|png/i
      if (!reg.test(suffix)) {
        this.$message.warning('仅支持jpg、jpeg、png格式的图片!')
        return false
      }
      // 请求时的额外参数,自定义
      this.otherReqParams.unitId = unitId;
      this.otherReqParams.loginName = loginName;
    }
  }
}
</script>

<style lang="less" scoped>
.hideUpload /deep/ .el-upload--picture-card {
  display: none;
}
// 其他的一些样式控制,根据情况自定义
.upload-cover /deep/ .up-tip{
  height: 128px;
  line-height: 128px;
  img {
    height: 30px;
  }
  .el-upload__text {
    position: absolute;
    top: 28px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
  }
}
.upload-cover /deep/ .el-upload-dragger {
  width: 341px;
  height: 148px;
}
.upload-cover /deep/ .el-upload__tip {
  color: #a7a3a3;
}
</style>
  • 父组件使用起来,就像下面这样:
<template>
	<div>
		<UploadPhotoFile :fileList="fileList"></UploadPhotoFile>
	</div>
</template>
// 导入组件
import UploadPhotoFile from './components/UploadPhotoFile.vue'
export default {
	components: {
		UploadPhotoFile
	},
	data() {
		return {
			fileList: [], //传入回显数组,格式为 {name: string, url: string}[]
		}
	},
	
}

写在最后

  • 以上就是以图片上传为例子,基于el-upload组件进行二次封装,结合了该组件的一些可选参数以及钩子函数还有样式透传去封装一个符合业务需求的文件上传组件;
  • 除此之外,在开发过程中当auto-upload=false即手动上传时,需要处理的情况也不一样;官方文档中有许多栗子,根据不同需求选择对应的模板组件去改造;以及上传的文件是音视频文件时,预览过程中会需要用到 video, audio等;
  • 最后,以上就是本文所有内容了,希望对你能有所帮助或是启发☀☀☀
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
封装el-upload实现文件上传,可以按照以下步骤进行操作: 1. 在el-upload组件中设置file-list属性为一个数组,用于存储上传成功的文件信息。 2. 创建一个方法用于处理上传文件。在这个方法中,使用FormData对象来创建一个文件表单对象,并将需要附加的参数添加到表单中。 3. 在el-upload组件中设置before-upload属性为一个方法,用于在上传文件之前进行文件格式的判断。在该方法中,可以通过获取文件的后缀名或其他方式来判断文件格式是否满足需求。 4. 在el-upload组件中设置action属性为上传文件的接口地址。 5. 在el-upload组件中设置on-success属性为一个方法,用于在文件上传成功后执行的操作。在该方法中,可以将上传成功的文件信息添加到file-list数组中。 下面是一个示例代码,演示了如何封装el-upload实现文件上传: ```javascript <template> <el-upload :action="uploadUrl" :before-upload="beforeUpload" :on-success="onSuccess" :file-list="fileList" multiple > <el-button>选择文件</el-button> </el-upload> </template> <script> export default { data() { return { uploadUrl: '/api/upload', fileList: [] }; }, methods: { beforeUpload(file) { // 在这里进行文件格式的判断,例如判断文件后缀名 const validExtensions = ['.xlsx', '.xls']; const extension = file.name.slice(file.name.lastIndexOf('.')); if (!validExtensions.includes(extension)) { this.$message.error('文件格式不正确'); return false; } return true; }, onSuccess(response, file) { // 在这里处理文件上传成功后的操作,例如将上传成功的文件信息添加到fileList数组中 this.fileList.push(file); } } }; </script> ``` 在这个示例中,el-upload组件的action属性设置为/api/upload,表示上传文件的接口地址。before-upload属性绑定了一个方法beforeUpload,用于文件格式的判断。on-success属性绑定了一个方法onSuccess,用于文件上传成功后的操作。file-list属性绑定了一个数组fileList,用于存储上传成功的文件信息。 通过以上步骤,可以封装el-upload组件实现文件上传,并在上传文件之前进行文件格式的判断。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [elemetUi 组件el-upload实现上传Excel文件的实例](https://download.csdn.net/download/weixin_38574410/13192019)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [vue+axios+el-upload实现文件上传(带参数):](https://download.csdn.net/download/weixin_38502290/14016804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [温控器LORA传输项目(lora)](https://download.csdn.net/download/m0_58719994/88269625)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值