1、业务需求
可以控制文件上传数量、格式,支持图片、pdf的预览、下载、删除,支持其他文件格式的下载删除。
2、效果截图

3、组件代码
<!-- -->
<template>
<div class="mainContainer">
<el-form @submit.native.prevent>
<el-upload
class="upload-demo"
:action="apiPath"
:accept="acceptType"
:limit="fileLimit"
:file-list="fileList"
:http-request="handleUploadFile"
>
<img
src="@/assets/mainPage/uploadFile.png"
alt="uploadFile"
v-if="isChangeFiles"
/>
<div slot="tip" class="el-upload__tip" v-if="isChangeFiles">
支持 {{ acceptType }} 格式,最多{{ fileLimit }}个
</div>
</el-upload>
<ul class="uploadView clearfix">
<li v-for="item in fileList" :key="item.id">
<div class="fileView" :title="item.name">
<img :src="getFileIconByName(item.name)" />
{{ item.name }}
</div>
<div class="uploadBtn">
<a
href="javascript:void(0)"
@click="handleRemove(item.id)"
v-if="isChangeFiles"
>删除</a
>
<a
href="javascript:void(0)"
v-if="isHasViewFunc(item.name)"
@click="handleView(item.url)"
>查看</a
>
<a
href="javascript:void(0)"
@click="handleDownload(item.name, item.url)"
>下载</a
>
</div>
</li>
</ul>
<!-- <el-upload class="upload-demo" :action="apiPath" :on-preview="handlePreview" :before-remove="beforeRemove"
:headers="headers"
:on-remove="handleRemove"
:accept="acceptType" :before-upload="beforeUpload" :limit="fileLimit" :on-exceed="handleExceed"
:file-list="fileList" :on-success="handleFileAdd">
<img src="@/assets/mainPage/uploadFile.png" alt="uploadFile" />
<div slot="tip" class="el-upload__tip">支持 {{ acceptType }} 格式,最多{{ fileLimit }}个</div>
</el-upload> -->
</el-form>
</div>
</template>
<script>
import axios from "axios";
import { downloadIamge, downFile } from "@/utils";
export default {
components: {},
props: {
isChangeFiles: {
type: Boolean,
default: true,
},
fileLimit: {
type: Number,
},
bizType: {
type: Number,
},
offlineflag: {
type: String,
},
fileList: {
type: Array,
default: [],
},
fileBelongId: {
type: Number,
},
acceptType: {
type: String,
default:
".xlsx,.xls,.png,.jpeg,.jpg,.gif,.ppt,pptx,.doc,.docx,.zip,.rar,.txt,.bmp,.tif,.pdf,.avi,.mp4,.mov", // 默认文件类型
},
},
data() {
return {
// apiPath: "/api/Attachment/UploadFile?bizType=" + this.bizType,
apiPath: "",
// headers: { "AuthorizationToken": localStorage.getItem("token") },
httpRequestUrl: "/api/Attachment/UploadFile?bizType=" + this.bizType,
};
},
computed: {},
watch: {},
methods: {
// 上传文件
handleUploadFile(params) {
let files = params.file;
// 文件上传前处理
this.beforeUploadFunc(files);
this.uploadFlieFunc(files);
},
// 文件上传方法
uploadFlieFunc(files) {
let self = this,
formData = new FormData();
formData.append("file", files);
try {
axios
.post(self.httpRequestUrl, formData, {
headers: {
AuthorizationToken: localStorage.getItem("token"),
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
if (res.data && res.data.returnData) {
let response = res.data.returnData;
let obj = {
name: files.name,
url: response.AttachmentPath,
id: response.AttachmentID,
};
if (!self.fileBelongId) {
// 当文件存储位置不是数组对象时
self.$emit("AddAttachment", response.AttachmentID, obj);
} else {
// 当文件存储位置为数组对象时
self.$emit(
"AddAttachment",
response.AttachmentID,
obj,
self.fileBelongId
);
}
} else {
self.$message.error("文件保存失败");
}
});
} catch (e) {
self.$message.error("文件保存失败");
}
},
// 文件上传成功时
// handleFileAdd(response, file, fileList) {
// let self = this;
// let obj = { name: file.name, url: response.returnData.AttachmentPath, id: response.returnData.AttachmentID }
// if(!this.fileBelongId) {
// // 当文件存储位置不是数组对象时
// self.$emit('AddAttachment', response.returnData.AttachmentID, obj);
// } else {
// // 当文件存储位置为数组对象时
// self.$emit("AddAttachment", response.returnData.AttachmentID, obj, this.fileBelongId);
// }
// },
// 文件删除
handleRemove(id) {
this.$confirm("文件删除后无法恢复,确定要删除文件?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
let file = { id: id };
if (!this.fileBelongId) {
this.$emit("removeFile", file);
} else {
this.$emit("removeFile", file, this.fileBelongId);
}
});
},
// 文件上传前处理
beforeUploadFunc(files) {
// 判断是否超过最大上传数量
if (this.fileList.length + 1 > this.fileLimit) {
this.$message.warning("已超过最大上传数量限制");
return;
}
let fileName = files.name;
// 获取文件类型
let typeArr = fileName.split(".");
let type = typeArr[typeArr.length - 1];
if (this.acceptType != "任意数据") {
let standFileTypeArr = this.acceptType.split(",");
// 判断是否符合上传文件类型
let arr = standFileTypeArr.filter((item) => item.substr(1) == type);
if (arr.length == 0) {
this.$message.error(`仅支持上传${this.acceptType}格式!`);
return false;
}
}
// let size = files.size;
// if(size / 1024 / 1024 > 10) {
// this.$message.error('单个文件大小上限10M');
// return false;
// }
// 如果是图片,这里要对图片进行压缩
// if(type == "png" || type == "jpeg" || type == "jpg" ) {
// this.compressPic(files)
// }
if (this.offlineflag == "1") {
this.$confirm("离线上传过程中不能关闭当前页面", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
let newpage = this.$router.resolve({
name: "offlineDataUpload",
});
window.open(newpage.href, "_blank");
});
}
},
// 压缩图片
compressPic(file) {},
// 根据文件名称显示图标
getFileIconByName(fileName) {
let iconType = fileName.split(".")[1];
let iconPic;
switch (iconType) {
case "xlsx":
case "xls":
iconPic = require("@/assets/mainPage/ico-xlsx.png");
break;
case "png":
case "jpeg":
case "jpg":
case "gif":
case "tif":
iconPic = require("@/assets/mainPage/ico-png.png");
break;
case "ppt":
case "pptx":
iconPic = require("@/assets/mainPage/ico-ppt.png");
break;
case "doc":
case "docx":
iconPic = require("@/assets/mainPage/ico-docx.png");
break;
case "rar":
case "zip":
iconPic = require("@/assets/mainPage/ico-zip.png");
break;
case "txt":
case "bmp":
iconPic = require("@/assets/mainPage/ico-txt.png");
break;
}
return iconPic;
},
// 是否显示查看按钮,仅当文件是图片或者ppt时可以查看
isHasViewFunc(fileName) {
let flag = false;
let iconType = fileName.split(".")[1];
if (
iconType == "png" ||
iconType == "jpeg" ||
iconType == "jpg" ||
iconType == "gif" ||
iconType == "ppt" ||
iconType == "pptx"
) {
flag = true;
}
return flag;
},
// 查看图片
handleView(url) {
let baseUrl = process.env.VUE_APP_DOWNLOAD_IP + url;
window.open(baseUrl, "_blank");
},
// 文件下载
handleDownload(name, url) {
let iconType = name.split(".")[1];
let baseUrl = process.env.VUE_APP_DOWNLOAD_IP + url;
if (iconType == "png" || iconType == "jpeg" || iconType == "jpg") {
downloadIamge(baseUrl, name);
} else {
downFile(baseUrl, name);
}
},
},
created() {},
mounted() {},
};
</script>
<style lang='scss'>
.el-upload-list {
display: none;
}
.uploadView {
width: 100%;
height: auto;
li {
width: 100%;
float: left;
padding: 0px 50px 0px 0px;
div {
float: left;
}
.fileView {
width: calc(100% - 150px);
height: 30px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.uploadBtn {
padding-left: 15px;
float: right;
a {
color: #5b6cea;
text-decoration: underline;
padding-left: 10px;
}
}
}
}
.upload-demo {
margin-bottom: 20px;
}
</style>
// 图片下载,只能在非跨域情况下使用
export function downloadIamge(imgsrc, name) {//下载图片地址和图片名
let image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
let a = document.createElement("a"); // 生成一个a元素
let event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
image.src = imgsrc;
}
// 普通文件下载
export function downFile(imgsrc, name) {
var a = document.createElement("a");
a.download = name;
a.href = imgsrc;
a.target="_blank";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
4、组件使用
<upload-multiple :bizType="bizType" :fileLimit="fileLimit" ref="addProjectUpload" :fileList="addProjectForm.FileList" :isChangeFiles="isChangeFiles" @AddAttachment="AddAttachment" @removeFile="removeFile" ></upload-multiple>
import { deleteFile } from "@/api/commonDoc"
import UploadMultiple from '@/components/UploadFileMultiple' // 多附件上传
export default {
components: { UploadMultiple },
data() {
return {
bizType: 0, //区分文件上传模块
fileLimit: 20, // 文件上传最大上限
addProjectForm: {
FileList: [] ,// 展示数组
FileAttachmentList: [], // 参数上传数组
},
isChangeFiles: true , // 是否需要新增、修改文件,控制内部按钮显示。true是 false否
}
},
methods: {
// 保存文件
AddAttachment(attachmentId, obj) {
this.addProjectForm.FileAttachmentList.push({ AttachmentID: attachmentId }); // 这里根据后台要求拼装数据格式
this.addProjectForm.FileList.push(obj);
this.addProjectForm = JSON.parse(JSON.stringify(this.addProjectForm)); // 做一次深拷贝,防止对象数据监听不到变化
},
// 文件删除
removeFile(file) {
let id = file.id;
let obj = { id: id };
deleteFile(obj).then(res => {
if (res.returnData) {
let index1 = 0;
this.addProjectForm.FileAttachmentList.some(res => {
if (res.AttachmentID == id) {
this.addProjectForm.FileAttachmentList.splice(index1, 1)
return true;
}
index1++;
})
let index2 = 0
this.addProjectForm.FileList.some(res => {
if (res.id == id) {
this.addProjectForm.FileList.splice(index2, 1);
return true;
}
index2++;
})
this.$message({
type: "success",
message: "删除成功"
})
return;
} else {
this.$message({
type: "error",
message: "删除失败"
})
return;
}
})
}
}
}
// 文件删除方法
export function deleteFile(id) {
return request({
url: "/Attachment/DeleteFile",
method: 'get',
params: id
})
}
5、备注
图标: