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