項目中經(jīng)常會用到文件上傳的功能叔收,為避免重復犯錯啸驯,現(xiàn)將近階段親測過的方法,記錄下
- 首先后端接口需求英上,需同時傳文件
FormData
和其他所需參數(shù)炭序,如下圖所示:
- 前端簡單的配置界面,如圖所示苍日,利
elementUI
組件el-upload
- 實現(xiàn)方法
關鍵點:
el-upload
的http-request
方法獲取文件File
信息和FormData
方式傳參
1.利用http-request
函數(shù)獲取上傳的文件File
信息
http-request
主要為覆蓋默認的上傳行為惭聂,可以自定義上傳的實現(xiàn),因需要實現(xiàn)手動上傳相恃,故應用到此方法
<template></template>
<template>
<el-upload
class="upload-demo"
ref="upload"
accept=".dat"
action=""
:http-request="httpRequest"
:auto-upload="false"
:file-list="fileList"
:on-change="handleFileChange"
>
<el-button slot="trigger" size="small" type="success">選取文件</el-button>
<div slot="tip" class="el-upload__tip" style="color: #ee4234">
{{ tips }}
</div>
</el-upload>
</template>
手動上傳時辜纲,會觸發(fā)
http-request
的回調(diào)函數(shù)httpRequest
httpRequest
方法
httpRequest(param) {
let fileObj = param.file; // 相當于input里取得的files
let fileName = fileObj.name;
let formData = new FormData(); // FormData 對象
formData.append("MultipartFile", fileObj); // 文件對象
formData.append("fileCreateName", fileName);//傳遞其他參數(shù)
this.$emit("upload", formData);
}
2.利用axio
的post
方法,實現(xiàn)與后端接口聯(lián)調(diào)
關鍵點:設置
headers
為multipart/form-data
注意:uploadFile
方法為封裝好的方法
//文件上傳
export function uploadFile(formData) {
return request({
url: '/dataFileRecord/add',
method: 'post',
data: formData,
isFormData: true,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
3.完整代碼拦耐,包括判斷上傳文件格式
和每次切換文件只顯示最新選擇的一個
自己封裝的
Upload
組件
<template>
<el-upload
class="upload-demo"
ref="upload"
accept=".dat"
action=""
:http-request="httpRequest"
:auto-upload="false"
:file-list="fileList"
:on-change="handleFileChange"
>
<el-button slot="trigger" size="small" type="success">選取文件</el-button>
<div slot="tip" class="el-upload__tip" style="color: #ee4234">
{{ tips }}
</div>
</el-upload>
</template>
<script>
export default {
name: "upload",
data() {
return {
tips: "只能上傳dat格式的文件",
fileList: [],
};
},
props: ["fileName"],
methods: {
init() {
this.fileList = [];
this.tips = "只能上傳dat格式的文件";
},
httpRequest(param) {
let fileObj = param.file; // 相當于input里取得的files
let fileName = fileObj.name;
let formData = new FormData(); // FormData 對象
formData.append("MultipartFile", fileObj); // 文件對象
formData.append("fileCreateName", fileName);
this.$emit("upload", formData);
},
isFormatValid(type) {
let pStrDAt = /\.dat?$/i;
return pStrDAt.test(type);
},
handleFileChange(file, fileList) {
this.beforeUpload(file);
if (fileList.length > 0) {
this.fileList = [fileList[fileList.length - 1]]; // 這一步耕腾,是 展示最后一次選擇的dat文件
}
},
beforeUpload(file) {
let fileName = file.name;
this.$emit("update:fileName", fileName);
let isDat = this.isFormatValid(fileName);
if (!isDat) {
this.tips = "當前選擇的文件格式不正確,請重新選擇杀糯!";
} else {
this.tips = "";
}
return isDat;
},
handleSubmit() {
if (!this.tips) {
this.$refs.upload.submit();
}
},
},
};
</script>
<style lang="scss" scoped>
.el-upload__tip {
color: #ee4234;
position: absolute;
top: 40px;
}
</style>
注意:點擊確定按鈕扫俺,調(diào)用組件
upload
的submit
方法,從而觸發(fā)httpRequest
方法固翰,實現(xiàn)手動上傳
this.$refs.upload.submit();
主頁面
<template>
<MainPanel
ref="panel"
:tableInfo="tableInfo"
:dialogInfo="dialogInfo"
@table-update="handlePageUpdate"
@table-edit="handleTableEdit"
@table-delete="handleTableDelete"
@btn-search="handleSearch"
@btn-add="handleAdd"
@btn-batch-delete="handleBatchDelete"
@dialog-confirm="handleDialogConfirm"
@dialog-cancel="handleDialogCancel"
>
<el-col :span="1" class="search-text">文件名稱:</el-col>
<el-col :span="3">
<el-input
v-model="searchFileName"
placeholder="請輸入文件名稱"
style="width: 100%"
clearable
></el-input>
</el-col>
<template #dialog>
<el-col :span="6">
<Upload
v-if="!isEdit"
ref="upload"
:fileName.sync="fileName"
@upload="handleUpload"
></Upload>
</el-col>
</template>
</MainPanel>
</template>
<script>
import MainPanel from "@/components/MainPanel";
import { uploadFile, getFileList, updateFile, delFile } from "@/api/api.js";
import Upload from "@/components/Upload";
export default {
name: "fileManage",
data() {
var columns = [
{
label: "文件名稱",
prop: "fileCreateName",
required: true,
},
{
label: "文件大小",
prop: "fileSize",
},
{
label: "文件類型",
prop: "fileType",
},
{
label: "創(chuàng)建時間",
prop: "createTime",
},
{
label: "更新時間",
prop: "updateTime",
},
];
var validateName = (rule, value, callback) => {
if (!this.dialogInfo.condition.fileCreateName) {
callback(new Error("文件名不能為空"));
} else {
callback();
}
};
return {
tableInfo: {
tableData: [],
columns: columns,
tableTotal: 0,
pageInfo: {},
},
dialogInfo: {
title: "文件上傳",
columns: columns.filter((item) => item.required),
condition: {
fileCreateName: "",
},
dialogWidth: "50%",
rules: {
fileCreateName: [
{ required: true, validator: validateName, trigger: "blur" },
],
},
},
isEdit: false,
condition: {
pageNo: 1,
pageSize: 10,
},
currentId: "",
fileName: "",
searchFileName: "",
};
},
components: { MainPanel, Upload },
watch: {
fileName(val) {
this.dialogInfo.condition.fileCreateName = val;
},
},
mounted() {
//獲取文件列表
this.getFileList();
},
methods: {
async getFileList() {
let pInfo = await getFileList(this.condition);
this.tableInfo.tableData = pInfo.data.data.content;
this.tableInfo.tableTotal = pInfo.data.data.totalElements;
},
handlePageUpdate(condition) {},
handleTableEdit(row) {
this.isEdit = true;
this.dialogInfo.title = "文件編輯";
this.currentId = row.id;
},
handleTableDelete(row) {
this.deleteFiles([row.id]);
},
handleBatchDelete(items) {
let idArray = items.map((item) => item.id);
this.deleteFiles(idArray);
},
handleAdd() {
this.isEdit = false;
this.dialogInfo.condition.fileCreateName = "";
if (this.$refs.upload) {
this.$refs.upload.init();
}
},
handleSearch() {
this.tableInfo.pageInfo = {
pageNo: 1,
pageSize: 10,
};
this.condition.pageNo = 1;
this.condition.pageSize = 10;
this.condition.param = JSON.stringify({
fileCreateName: this.searchFileName,
});
this.getFileList();
},
handleDialogConfirm() {
if (this.isEdit) {
this.updateFile();
} else {
if (this.$refs.upload) {
this.$refs.upload.handleSubmit();
}
}
},
handleDialogCancel() {
this.fileName = "";
},
addFile(formData) {
uploadFile(formData).then((res) => {
if (res.data.code === "0") {
this.handleSuccess("上傳");
} else {
this.handleError("上傳");
}
});
},
updateFile() {
updateFile({
fileCreateName: this.dialogInfo.condition.fileCreateName,
id: this.currentId,
}).then((res) => {
if (res.data.code === "0") {
this.handleSuccess("更新");
} else {
this.handleError("更新");
}
});
},
deleteFiles(idArray) {
delFile(idArray).then((res) => {
if (res.data.code === "0") {
this.handleSuccess("刪除");
} else {
this.handleError("刪除");
}
});
},
handleUpload(formData) {
this.addFile(formData);
},
handleSuccess(type) {
this.$message({
type: "success",
message: "文件" + type + "成功狼纬!",
});
if (this.$refs.panel) {
this.$refs.panel.init();
}
this.fileName = "";
this.getFileList();
},
handleError(type) {
this.$message({
type: "error",
message: "文件" + type + "失敗羹呵,請檢查服務連接!",
});
},
},
};
</script>
<style lang="scss" scoped>
</style>