vue实战–vue+elementUI实现多文件上传+预览(word/PDF/图片/docx/doc/xlxs/txt)
需求
最近在做vue2.0+element UI的项目中遇到了一个需求:需求是多个文件上传的同时实现文件的在线预览功能。需求图如下:


看到这个需求的时候,小栗脑袋一炸。并不知道该如何下手,之前的实践项目中也并没有遇到相似的功能。因此也废了一番功夫想要实现这样一个功能。
首先先查看elemnt UI的官方文档发现,大部分的实现文件上传效果的功能,即使可以提供预览的功能,但是不能指定该功能的样式和内容有一定的局限性
然后小栗查找“多文件上传预览、PDF预览、word预览等关键词”,发现大部分的大佬的方法都是实现了图片预览,并没有实现多文件上传(也可能是因为我并没有找到相关的功能)。
因此小栗决定自己封装这个功能,并希望有朋友能在这个的基础上进行调整优化。期待你们的参与哦~~
话不多说,上才艺
实现需求
1、利用on-preview+window.open()实现简易版预览效果
查看element UI文档后发现el-upload里面有一个Attribute叫on-preview( 点击文件列表中已上传的文件时的钩子)是专门用来做文件预览的。点击文件就可以出发该函数。再结合window.open()方法可以直接完成一个新开窗口页的查看文件
代码如下:
- HTML部分
//on-preview="Previewf"是必须的也是预览的关键
上传文件
- methods部分
Previewf(file) {
console.log(file);
// window.open(file.response)
if (file) {
const addTypeArray = file.name.split(".");
const addType = addTypeArray[addTypeArray.length - 1];
console.log(addType);
if (addType === "pdf") {
let routeData = this.$router.resolve({
path: "/insurancePdf",
query: { url: file.response, showBack: false },
});
window.open(routeData.href, "_blank");
}
//".rar, .zip, .doc, .docx, .xls, .txt, .pdf, .jpg, .png, .jpeg,"
else if (addType === "doc" || addType === "docx" || addType === "xls") {
window.open(
"http://view.officeapps.live.com/op/view.aspx?src=" + file.response
);
} else if (addType === "txt") {
window.open(file.response);
} else if (["png", "jpg", "jpeg"].includes(addType)) {
window.open(file.response);
} else if (addType === "rar" || addType === "zip") {
this.$message({
message: "该文件类型暂不支持预览",
type: "warning",
});
return false;
}
}
},
- 功能预览

点击蓝色的文件部分就可以出现新开页面,这个简易的利用element UI就完成了这个功能啦~有没有觉得还是不那么难呢?
2、封装组件实现更完整的上传完成、预览功能
上述的功能可以完成预览,但与我们的需求有一部分的出入,不能够完全满足我的业务需求,因此在element UI的基础上,我进行了组件封装,以求完成以下功能:

话不多说,还是上代码:
- HTML部分
/*
重点关注的代码:
:show-file-list="false"
ref="contentWrap
*/
将文件拖到此处,或点击上传
支持扩展名:.rar .zip .doc .docx .xls .txt .pdf .jpg .png .jpeg,最多上传5个文件,每个大小不超过50Mb
0">
70"
@click="noHidden = !noHidden"
>
{{ noHidden ? "收起" : "更多" }}
- methods部分
import UploadfileItem from "";
export default {
components: {
UploadfileItem,
},
data() {
return {
noHidden: true,
wrapHeight: 0,
delDialogitem: 0,
imgLoad: false,
centerDialogVisible: false,
file-list:[],
},
};
},
methods: {
cancelFile(file) {
console.log(file);
},
// 上传文件只能添加五条
uploadFileClick(event) {
if (this.formLabelAlign.annex.length === 5) {
this.$message({
type: "warning",
message: "最多只可以添加五条",
});
event.stopPropagation();
return false;
}
},
//
onSuccess(response, file, annex) {
if (!response) {
this.$message.error("文件上传失败");
} else {
this.imgLoad = false;
this.$message({
message: "上传成功!",
type: "success",
});
}
},
beforeUpload(file) {
console.log(file);
},
handleExceed(files, ) {
console.log(file);
},
};
- UploadfileItem组件内容
{{file.fileName}}
{{file.size | toKB}}kb
预览
下载
上传完成
export default {
props: {
file: {
type: Object,
default: {}
},
showDel: {
type: Boolean,
default: false
}
},
data() {
return {
imgDlgVisible: false,
imgUrl: '',
pdfUrl: '',
imgsrc: {
/*
*imgsrc 是关于内部静态图片的显示的路径,需要自己设置
*示例"xls": require('@/assets/image/xls.png'),
xis的文件所需要加载的路径是;assets文件下的image文件夹下的xls.png
*/
"rar": require('@'),
"zip": require('@'),
"pdf": require('@'),
"jpg": require('@'),
"jpeg": require('@'),
"png": require('@'),
"doc": require('@'),
"docx": require('@'),
"txt": require('@'),
"xls": require('@/assets/image/xls.png'),
}
}
},
filters: {
toKB(val) {
return (Number(val) / 1024).toFixed(0);
}
},
methods: {
cancelHanlder(item) {
this.$emit('cancel', item)
},
previewHandler(data) {
if (data) {
const addTypeArray = data.split(".");
const addType = addTypeArray[addTypeArray.length - 1];
if (addType === "pdf") {
let routeData = this.$router.resolve({ path: "/insurancePdf", query: { url: data, showBack: false } });
window.open(routeData.href, '_blank');
} else if (addType === "doc") {
window.open(
`https://view.officeapps.live.com/op/view.aspx?src=${data}`
);
} else if (addType === "txt") {
window.open(`${data}`);
} else if (['png','jpg','jpeg'].includes(addType)) { // 图片类型
this.imgDlgVisible = true
this.imgUrl = data
}
}
},
}
.file-style-box {
padding: 10px 10px 0 0;
}
.imgDlgBox {
.el-dialog {
.el-dialog__body {
text-align: center;
img {
width: 700px;
height: auto;
}
}
}
}
.upload-file-item {
background: #FAFAFA;
border-radius: 4px;
padding: 5px 10px;
margin-bottom: 10px;
display: flex;
font-size: 14px;
width: 236px;
box-sizing: border-box;
position: relative;
img {
width: 32px;
height: 40px;
margin-top: 5px;
margin-right: 10px;
}
.option {
display: flex;
align-items: center;
justify-content: space-between;
}
.file-name {
width: 163px;
display: flex;
flex-wrap: nowrap;
font-size: 14px;
color: #333;
font-weight: 400;
.name {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.end {
flex: 0 0 auto;
}
.el-button{
border: none;
padding: 0px;
width: 90%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.size {
color: #969696;
}
.success {
color: #78C06E;
}
.delBtn {
position: absolute;
top: -14px;
right: -18px;
cursor: pointer;
img {
width:16px;
height:16px
}
}
// .del {
// color: #E1251B;
// cursor: pointer;
// }
.preview {
color: #0286DF;
cursor: pointer;
}
.mr10 {
margin-right: 10px;
}
}
- 效果图


以上就可以实现实现多文件上传+预览(word/PDF/图片/docx/doc/xlxs/txt)啦,希望这样的实现方式也对你有帮助哦
如果有帮助请别忘了点赞、评论、互动、关注哦~
追加关于评论区问的比较多的问题回复
1、imgsrc路径
imgsrc: {
"rar": require('@/assets/material/zip.png'),
}
这个位置会报错
这里报错是因为此处的内容是静态资源,他是我们预览图片的一些细节,长成如下图所示:


你本地应该也需要配置这样一个文件夹的路径就可以啦。
2、显示原本elementui的那个上传样式
重点关注el- upload的代码 :show-file-list="false" //关闭原来的上传样式 ref="contentWrap //这个是通过父子组件传值将子组件的页面
3、file.response显示没有这个属性和方法
file.response是element UI的内置的组件的方法,引入element UI使用文件上传组件就可以实现
我之前写这儿的file.response 时候,有一个传递值也有问题,好像是element UI的钩子函数的问题,你先打印file。然后看是不是file.response ,不是的话 查看一下file的其他属性,有一个是跟回调相关的返回值
就可以解决啦
4、https://view.officeapps.live.com/op/view.aspx?src=${data}是干嘛的?预览PDF需要安装其他的插件吗?
首先:不需要再安装其他预览资源加载包,所有的预览都是通过windom.open()方法打开一个新窗口预览。
PDF的预览时使用的office官方的接口文档:`https://view.officeapps.live.com/op/view.aspx?src=${data}就可以预览PDF文档了。
图片的预览是通过dialog的弹窗实现的,就简单一个弹窗
rar和zip不支持预览,只能下载查看
如果有帮助请别忘了点赞、评论、互动、关注哦~
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/f723beeda0.html
