環境:vue2.5.6+axios0.18.1+element-ui2.15.1
在使用element UI的upload元件上傳檔案時,遇到一些問題,網上的說法不盡如是,在此記錄
其實最主要的估計就是axios相關的問題,因我們平時開發的vue專案都是封裝過axios後進行api的呼叫,但上傳操作跟一般的api請求不同,所有總是報錯,故需要建立新的axios範例。
檔案上傳型別可以在el-upload的accept中進行定義,上傳時會進行一定的過濾。
例如圖片型別:accept=".png, .jpeg"
import Vue from "vue";
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:8080", // 後臺地址
withCredentials: false,
timeout: 10000
});
Vue.prototype.axiosUpload = instance;
<template>
<el-dialog :title="title" :visible.sync="upLoadVisible" width="30%" @close="closeDialog">
<div class="upload-box">
<el-upload
ref="upload"
drag
class="upload-demo"
accept=".xls,.xlsx"
action="#"
:limit="1"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:auto-upload="false"
:before-upload="beforeUpload"
:http-request="uploadHttpRequest"
>
<i class="el-icon-upload" />
<div class="el-upload__text">
將檔案拖到此處,或<em style="color: #409eff">點選上傳</em>
</div>
<div slot="tip" class="el-upload__tip">
只能上傳xls/xlxs檔案, 檔案大小不超過10M
</div>
</el-upload>
<el-progress
v-if="processVisible"
:percentage="processPercent"
:text-inside="true"
:stroke-width="24"
:status="processStatus"
style="margin: 20px 0;"
/>
<el-alert
v-if="tipVisible"
:title="tipTitle"
type="error"
@close="tipVisible = false"
/>
<el-button
style="margin: 10px 0;"
icon="el-icon-upload2"
size="small"
type="primary"
:loading="uploading"
@click="submitUpload"
>
上傳到伺服器
</el-button>
<el-button
style="margin-left: 0"
icon="el-icon-circle-close"
size="small"
@click="cancelUpload"
>
取 消
</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "上傳檔案"
},
upLoadVisible: {
type: Boolean,
default: false
},
uploadUrl: { // 上傳檔案的api
type: String,
default: ""
}
},
data() {
return {
fileList: [],
uploading: false,
processPercent: 5,
processStatus: 'success',
processVisible: false,
tipVisible: false,
tipTitle: '',
timer: null
};
},
methods: {
// 上傳檔案之前的勾點:判斷上傳檔案格式、大小等,若返回false則停止上傳
beforeUpload(file) {
// 檔案型別
const isType = file.type === "application/vnd.ms-excel";
const isTypeComputer =
file.type ===
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
const fileType = isType || isTypeComputer;
if (!fileType) {
this.$message.error("上傳檔案只能是xls/xlsx格式!");
}
// 檔案大小限制為10M
const fileLimit = file.size / 1024 / 1024 < 10;
if (!fileLimit) {
this.$message.error("上傳檔案大小不超過10M!");
}
return fileType && fileLimit;
},
// 自定義上傳方法,param是預設引數,可以取得file檔案資訊,具體資訊如下圖
async uploadHttpRequest(param) {
const that = this;
this.uploading = true; // 顯示按鈕載入中
this.processVisible = true; // 顯示進度條
this.processPlus();
// FormData物件,新增引數只能通過append('key', value)的形式新增
const formData = new FormData();
// 新增檔案物件
formData.append("file", param.file);
const config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
this.axiosUpload.post(this.uploadUrl, formData, config).then(res => {
// 這裡的res需根據後臺返回情況判斷
if (res.data.code === 200) {
this.processPercent = 100;
that.uploading = false;
this.processVisible = false;
this.timer = null;
that.$emit("closeUpload");
that.$message.success(res.data.msg);
} else {
this.processPercent = 100;
this.processStatus = "exception";
this.tipVisible = true;
this.tipTitle = res.data.msg;
this.uploading = false;
}
}).catch(reject => {
console.log(reject)
})
},
// 上傳至伺服器
submitUpload() {
this.$refs.upload.submit();
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
cancelUpload() {
this.$refs.upload.clearFiles(); // 清除上傳檔案物件
this.fileList = []; // 清空選擇的檔案列表
this.$emit("closeUpload");
},
// 前期進度條增加
processPlus() {
this.timer = setInterval(() => {
if (this.processPercent < 90) {
this.processPercent += 10;
}
}, 200)
},
closeDialog() {
this.$emit('closeUploadDialog');
}
}
};
</script>
<style scoped>
.upload-box {
display: flex;
flex-direction: column;
justify-content: center;
}
.upload-demo {
display: flex;
flex-direction: column;
align-items: center;
}
</style>