vue+element UI + axios封装文件上传及进度条组件

Easter79
• 阅读 1073

1.前言

之前在做项目的时候,需要实现一个文件上传组件并且需要有文件上传进度条,现将之前的实现过程简单记录一下,希望可以帮助到有需要的人。

项目用的是Vue框架,UI库使用的是element UI,前后端交互请求使用的是Vue官方推荐的axios。其中,UI方面主要使用了element UI库中的Upload文件上传组件、Progress 进度条组件。

2.文件上传

文件上传功能使用element UI库中的Upload文件上传组件实现,代码如下:

<div class="uploadfile">
      <el-upload
        ref="upload"
        class="upload-demo"
        :before-upload="beforeUpload"
        drag
        :auto-upload="false"
        :on-exceed="handleExceed"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击选择文件</em></div>
      </el-upload>
      <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传</el-button>
    </div>

当点击上传按钮,会触发submitUpload函数,同时该函数也会触发beforeUpload函数:

beforeUpload(file){
            let fd = new FormData();
            fd.append('file', file);
            let config = {
              onUploadProgress: progressEvent => {
                let complete = (progressEvent.loaded / progressEvent.total ).toFixed(2) * 100 ;
                this.percentage = complete;
                if (this.percentage >= 100){
                  this.dialogVisible = true
                }
              },
              headers: {
                'Content-Type': 'multipart/form-data'
              }
            };
            this.$axios.post(this.url,fd,config)
              .then((res)=>{

              })
              .catch((err)=>{

              })
          },
          submitUpload(){
            this.loading = true;
            this.tips = '正在上传中。。。';
            this.$refs.upload.submit();
          },

3.进度条

当点击上传后,整个页面被遮罩层遮挡,并显示上传进度:

<!--遮罩层-->
    <div class="loading" v-if="loading" >
      <h4 class="tips">{{tips}}</h4>
      <!--进度条-->
      <el-progress type="line" :percentage="percentage" class="progress" :show-text="true"></el-progress>
    </div>

进度条关键代码:

进度条的实现主要依靠axios中提供的onUploadProgress函数,该函数提供了文件已上传部分的大小progressEvent.loaded和文件总大小progressEvent.total,利用这两个数据我们就可以计算出已经上传文件的进度。

beforeUpload(file){
            let fd = new FormData();
            fd.append('file', file);
            let config = {
              onUploadProgress: progressEvent => {
                //progressEvent.loaded:已上传文件大小
                //progressEvent.total:被上传文件的总大小
                let complete = (progressEvent.loaded / progressEvent.total ).toFixed(2) * 100 ;
                this.percentage = complete;
                if (this.percentage >= 100){
                  this.dialogVisible = true
                }
              },
              headers: {
                'Content-Type': 'multipart/form-data'
              }
            };
            this.$axios.post(this.url,fd,config)
              .then((res)=>{

              })
              .catch((err)=>{

              })
          },

4.全部代码

封装好组件后,我们只需在父组件中调用该组件并传入文件上传到的目的url即可。

<UploadFile :url="/test/"/>

以下是该组件UploadFile.vue的全部代码:

<template>
  <div>
    <!--文件上传入口-->
    <div class="uploadfile">
      <el-upload
        ref="upload"
        class="upload-demo"
        :before-upload="beforeUpload"
        drag
        :auto-upload="false"
        :on-exceed="handleExceed"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击选择文件</em></div>
      </el-upload>
      <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传</el-button>
    </div>
    <!--遮罩层-->
    <div class="loading" v-if="loading" >
      <h4 class="tips">{{tips}}</h4>
      <!--进度条-->
      <el-progress type="line" :percentage="percentage" class="progress" :show-text="true"></el-progress>
    </div>
    <!--上传完成提示对话框-->
    <el-dialog
      title="提示"
      :visible="dialogVisible"
      width="30%"
      :modal-append-to-body='false'
    >
      <span>文件上传成功</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="ensure">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
    import Vue from 'vue'
    import {Upload,Button,Progress,Dialog} from 'element-ui';
    Vue.use(Upload);
    Vue.use(Button);
    Vue.use(Progress);
    Vue.use(Dialog);

    export default {
        name: "UploadFile",
        data(){
          return {
            loading:false,
            percentage:0,
            tips:'',
            dialogVisible:false
          }
        },
        props:['url'],
        methods:{
          beforeUpload(file){
            let fd = new FormData();
            fd.append('file', file);
            let config = {
              onUploadProgress: progressEvent => {
                //progressEvent.loaded:已上传文件大小
                //progressEvent.total:被上传文件的总大小
                let complete = (progressEvent.loaded / progressEvent.total ).toFixed(2) * 100 ;
                this.percentage = complete;
                if (this.percentage >= 100){
                  this.dialogVisible = true
                }
              },
              headers: {
                'Content-Type': 'multipart/form-data'
              }
            };
            this.$axios.post(this.url,fd,config)
              .then((res)=>{

              })
              .catch((err)=>{

              })
          },
          handleExceed(){

          },
          submitUpload(){
            this.loading = true;
            this.tips = '正在上传中。。。';
            this.$refs.upload.submit();
          },
          ensure(){
            this.dialogVisible = false;
            this.loading = false;
          }
        }
    }
</script>

<style scoped>
  .uploadfile{
    width: 200px;
    height: 200px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
   .loading{
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background: black;
    opacity: 0.8;
  }
  .progress{
    width: 200px;
    height: 200px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
  .tips{
    color: #409eff;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -100px;
    margin-top: -150px;
  }

</style>

5.效果演示

主要说明原理,UI就自行发挥吧。 vue+element UI + axios封装文件上传及进度条组件

点赞
收藏
评论区
推荐文章
Immortal Immortal
2年前
vue项目中使用element-ui实现excel表格上传
恰逢项目中要实现excel表格上传,度娘甚久,得此一文,留之。原文:https://blog.csdn.net/qq36718999/article/details/95387542需求vuecli搭建前端项目,并使用elementui实现本地excel表格上传。(1)限制上传文件只能是xls、xlsx格式;(2)限制上传文件大小不能超过2MB
Alex799 Alex799
3年前
5款vue前端UI框架
Vue.js是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue采用自底向上增量开发的设计。实用的Vue.js组件库可以帮助我们快速搭建页面,下面介绍小编认为比较受欢迎的五个vue前端ui框架。TOP5——VueBluVueBlu是基于Vuejs和Bulma开发的开源UI组件库。旨在为PC端的前端开发(特别是中后台产品)提供一个快速且灵
Easter79 Easter79
2年前
Vue (ElementUI)在前端浏览器读取文本文件(如JSON)内容
有时想要导入数据到数据库,需要上传相应的文本文件,而这种文件基本上是一次消耗品,也就是上传到后端服务读取了数据之后需要将上传的该文件进行删除。vue文件template中的代码:<eluploadaction"":onchange"readFile"
徐小夕 徐小夕
3年前
基于create-react-app打包编译自己的第三方UI组件库并发布到npm
前言这篇文章主要是总结一下我们在工作中如何为公司开发内部的第三方UI组件,并通过npminstall的方式安装的一些步骤和思路。在学习完这套发布方法后大家也可以快速的发布自己的UI库到npm,供他人使用,就比如elementUI或者AntDesign。如果想学习如何发布一个js库或者框架,那么使用rollup更为适合,可以参考如下文章:前端组
Easter79 Easter79
2年前
springboot+vue 登录页面(一)
首先了解的技术点是:后台:springboot,mybatis,mybatis逆向工程,mysql,日志前端:nodejs,npm,cnpm,vue,vuecli,webpack,elementui,router,axios开发工具:idea,webstorm该项目前端使用的是vue,目的是实现前后端分离后台:1.选择spr
Easter79 Easter79
2年前
struts2框架实现上传文件进度条功能
      1.在实现上传进度条功能中,主要是的思想是利用struts2中定义的ProgressListener(进度监听器),里面有一个update(longreadedBytes,longtotalBytes,intcurrentItem)方法,当文件用二进制文件来进行上传时,每上传一部分数据都会去调用这个update方法,update中得到s
徐小夕 徐小夕
3年前
3分钟教你用原生js实现具有进度监听的文件上传预览组件
本文主要介绍如何使用原生js,通过面向对象的方式实现一个文件上传预览的组件,该组件利用FileReader来实现文件在前端的解析,预览,读取进度等功能,并对外暴露相应api来实现用户自定义的需求,比如文件上传,进度监听,自定义样式,读取成功回调等。组件设计架构如下:(https://imghelloworld.osscnbeijing.
云计算笔记 云计算笔记
1年前
实现一个大文件切片上传+断点续传功能
相信每个切图工程师,都接触过文件上传的需求,一般的小文件,我们直接使用inputfile,然后构造一个newFormData()对象,扔给后端就可以了。如果使用了Antdesign或者elementui之类的ui库,那更简单,直接调用一下api即可。当然了,复杂一些的,市面上也有不少优秀的第三方插件,比如WebUploader。但是作为一
Stella981 Stella981
2年前
React Hooks的999999个好处
最近前几个月开始,新项目都开始完全使用typescripthooks,先不说typescript吧,hooks是真的香🤣1.更好的分离页面和逻辑,重用逻辑的方法现在前端项目的组件化,一般都是基于最基础的UI组件库(里面也有组件的功能逻辑),加上业务逻辑,封装一个个component,container。组件是UI逻辑的复用,
京东云开发者 京东云开发者
10个月前
前端文件上传的几种交互造轮子 | 京东云技术团队
前端文件上传本来是一个常规交互操作,没什么特殊性可言,但是最近在做文件上传,需要实现截图粘贴上传,去找了下有没有什么好用的组件,网上提供的方法有,但是没找完整的组件来支持cv上传,经过了解发现可以用剪贴板功能让自己的cv实现文件上传,于是自己就整合了目前几种文件上传的交互方式,码了一个支持cv的vue3文件上传组件(造个轮子)。
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k