1.前言
以前在作項目的時候,須要實現一個文件上傳組件而且須要有文件上傳進度條,現將以前的實現過程簡單記錄一下,但願能夠幫助到有須要的人。javascript
項目用的是Vue框架,UI庫使用的是element UI,先後端交互請求使用的是Vue官方推薦的axios。其中,UI方面主要使用了element UI庫中的Upload
文件上傳組件、Progress
進度條組件。html
2.文件上傳
文件上傳功能使用element UI庫中的Upload
文件上傳組件實現,代碼以下:vue
<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
函數:java
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.進度條
當點擊上傳後,整個頁面被遮罩層遮擋,並顯示上傳進度:ios
<!--遮罩層--> <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>
進度條關鍵代碼:element-ui
進度條的實現主要依靠axios
中提供的onUploadProgress
函數,該函數提供了文件已上傳部分的大小progressEvent.loaded
和文件總大小progressEvent.total
,利用這兩個數據咱們就能夠計算出已經上傳文件的進度。axios
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
的所有代碼:app
<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就自行發揮吧。 框架