vue+element UI + axios封裝文件上傳及進度條組件 (轉)

閱讀目錄

 


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就自行發揮吧。



 

免責聲明

  • 本博客所有文章僅用於學習、研究和交流目的,歡迎非商業性質轉載。

原爲鏈接:https://www.cnblogs.com/wangjiachen666/p/9700730.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章