vue+elementUI實現(xiàn)多文件上傳與預覽功能實戰(zhàn)記錄(word/PDF/圖片/docx/doc/xlxs/txt)
需求
最近在做vue2.0+element UI的項目中遇到了一個需求:需求是多個文件上傳的同時實現(xiàn)文件的在線預覽功能。需求圖如下:


看到這個需求的時候,小栗腦袋一炸。并不知道該如何下手,之前的實踐項目中也并沒有遇到相似的功能。因此也廢了一番功夫想要實現(xiàn)這樣一個功能。
首先先查看elemnt UI的官方文檔發(fā)現(xiàn),大部分的實現(xiàn)文件上傳效果的功能,即使可以提供預覽的功能,但是不能指定該功能的樣式和內(nèi)容有一定的局限性
然后小栗查找“多文件上傳預覽、PDF預覽、word預覽等關鍵詞”,發(fā)現(xiàn)大部分的大佬的方法都是實現(xiàn)了圖片預覽,并沒有實現(xiàn)多文件上傳(也可能是因為我并沒有找到相關的功能)。
因此小栗決定自己封裝這個功能,并希望有朋友能在這個的基礎上進行調(diào)整優(yōu)化。期待你們的參與哦~~
話不多說,上才藝
實現(xiàn)需求
1、利用on-preview+window.open()實現(xiàn)簡易版預覽效果
查看element UI文檔后發(fā)現(xiàn)el-upload里面有一個Attribute叫on-preview( 點擊文件列表中已上傳的文件時的鉤子)是專門用來做文件預覽的。點擊文件就可以出發(fā)該函數(shù)。再結合window.open()方法可以直接完成一個新開窗口頁的查看文件
代碼如下:
HTML部分
//on-preview="Previewf"是必須的也是預覽的關鍵
<el-upload
class="upload-demo"
:action="uploadUrl"
:on-success="handlePreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:on-preview="Previewf"
multiple
:limit="5"
:on-exceed="handleExceed"
:file-list="file-list"
:accept="accepts"
>
<el-button icon="el-icon-upload2" @click="uploadFileClick($event)"
>上傳文件</el-button
>
</el-upload>
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;
}
}
},
功能預覽

點擊藍色的文件部分就可以出現(xiàn)新開頁面,這個簡易的利用element UI就完成了這個功能啦~有沒有覺得還是不那么難呢?
2、封裝組件實現(xiàn)更完整的上傳完成、預覽功能
上述的功能可以完成預覽,但與我們的需求有一部分的出入,不能夠完全滿足我的業(yè)務需求,因此在element UI的基礎上,我進行了組件封裝,以求完成以下功能:

話不多說,還是上代碼:
HTML部分
/*
重點關注的代碼:
:show-file-list="false"
ref="contentWrap
*/
<el-upload
class="upload-demo"
ref="uploadCom"
:show-file-list="false"
:action="uploadUrl"
:on-success="onSuccess"
:on-remove="handleRemove"
:before-upload="beforeUpload"
multiple
:limit="5"
:on-exceed="handleExceed"
:file-list="file-list"
:accept="accepts"
>
<el-button icon="el-icon-upload2" @click="uploadFileClick($event)"
>將文件拖到此處,或<em>點擊上傳</em></el-button
>
<div slot="tip" class="el-upload__tip">
支持擴展名:.rar .zip .doc .docx .xls .txt .pdf .jpg .png .jpeg,最多上傳5個文件,每個大小不超過50Mb
</div>
</el-upload>
<div class="flex mt20" v-if="file-list.length > 0">
<div
class="items-wrap"
ref="contentWrap"
:style="wrapHeight <= 70 ? 'height: auto' : `height: 60px;`"
:class="{ noHidden: noHidden }"
>
<uploadfile-item
v-for="(item, index) in file-list"
:key="index"
:file="item"
@cancel="cancelFile"
:showDel="true"
class="mr20"
></uploadfile-item>
</div>
<div
class="on-off"
v-if="wrapHeight > 70"
@click="noHidden = !noHidden"
>
{{ noHidden ? "收起" : "更多" }}
</div>
</div>
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組件內(nèi)容
<template>
<div class="file-style-box">
<div class='upload-file-item'>
<img :src="imgsrc[getEnd(file.fileName)]" alt="">
<div>
<p class='file-name'>
<span class='name'>{{file.fileName}}</span>
</p>
<div class='option'>
<span class='size'>{{file.size | toKB}}kb</span>
<div>
<span v-if='showDel && (isPdf(file) || isImg(file))' @click='previewHandler(file.url)' class='preview mr10'>預覽</span>
<a v-if='!showDel' @click='downLoadHandler' class='preview' :href="file.url" rel="external nofollow" >下載</a>
<span v-if='showDel' class='mr10 success'>上傳完成</span>
</div>
</div>
<div class='delBtn' v-if='showDel' @click='cancelHanlder(file)'>
<img src="@/assets/public/tips-err.png" alt="">
</div>
</div>
</div>
<el-dialog
title="圖片預覽"
width="800px"
class="imgDlgBox"
:visible.sync="imgDlgVisible"
:close-on-click-modal="true"
:modal="false"
append-to-body
>
<img :src="imgUrl" alt="">
</el-dialog>
</div>
</template>
<script>
export default {
props: {
file: {
type: Object,
default: {}
},
showDel: {
type: Boolean,
default: false
}
},
data() {
return {
imgDlgVisible: false,
imgUrl: '',
pdfUrl: '',
imgsrc: {
/*
*imgsrc 是關于內(nèi)部靜態(tài)圖片的顯示的路徑,需要自己設置
*示例"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
}
}
},
}
</script>
<style lang='scss'>
.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;
}
}
</style>
效果圖


以上就可以實現(xiàn)實現(xiàn)多文件上傳+預覽(word/PDF/圖片/docx/doc/xlxs/txt)啦,希望這樣的實現(xiàn)方式也對你有幫助哦
追加關于問的比較多的問題回復
1、imgsrc路徑
imgsrc: {
"rar": require('@/assets/material/zip.png'),
}
這個位置會報錯
這里報錯是因為此處的內(nèi)容是靜態(tài)資源,他是我們預覽圖片的一些細節(jié),長成如下圖所示:


你本地應該也需要配置這樣一個文件夾的路徑就可以啦。
2、顯示原本elementui的那個上傳樣式
重點關注el- upload的代碼 :show-file-list="false" //關閉原來的上傳樣式 ref="contentWrap //這個是通過父子組件傳值將子組件的頁面
3、file.response顯示沒有這個屬性和方法
file.response是element UI的內(nèi)置的組件的方法,引入element UI使用文件上傳組件就可以實現(xiàn)
我之前寫這兒的file.response 時候,有一個傳遞值也有問題,好像是element UI的鉤子函數(shù)的問題,你先打印file。然后看是不是file.response ,不是的話 查看一下file的其他屬性,有一個是跟回調(diào)相關的返回值
就可以解決啦
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的彈窗實現(xiàn)的,就簡單一個彈窗
rar和zip不支持預覽,只能下載查看
總結
到此這篇關于vue+elementUI實現(xiàn)多文件上傳與預覽功能(word/PDF/圖片/docx/doc/xlxs/txt)的文章就介紹到這了,更多相關vue+elementUI多文件上傳預覽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue中在data里面調(diào)用method方法的實現(xiàn)
這篇文章主要介紹了Vue中在data里面調(diào)用method方法的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
vue2.x版本中computed和watch的使用及關聯(lián)和區(qū)別
這篇文章主要介紹了vue2.x版本中computed和watch的使用及關聯(lián)和區(qū)別,文章圍繞主題展開詳細的內(nèi)容介紹,需要的小伙伴可以參考一下2022-07-07
vue select選擇框數(shù)據(jù)變化監(jiān)聽方法
今天小編就為大家分享一篇vue select選擇框數(shù)據(jù)變化監(jiān)聽方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Vue數(shù)據(jù)驅(qū)動表單渲染,輕松搞定form表單
這篇文章主要介紹了Vue數(shù)據(jù)驅(qū)動表單渲染,輕松搞定form表單,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-07-07
vue3+electron12+dll開發(fā)客戶端配置詳解
本文將結合實例代碼,介紹vue3+electron12+dll客戶端配置,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-06-06

