Vue 封装el-upload通用组件, 实现pdf、img混排,支持预览
使用vue-pdf加载pdf文件npm install --save vue-pdfel-upload设置上传文件格式,自定义排版,通过过slot实现<el-uploadref="elUpload":action="baseUrl"list-type="picture-card":limit="limit":class="{ hide: disabled }".
·
- 使用vue-pdf加载pdf文件
npm install --save vue-pdf
-
el-upload设置上传文件格式,自定义排版,通过过slot实现
<el-upload ref="elUpload" :action="baseUrl" list-type="picture-card" :limit="limit" :class="{ hide: disabled }" :disabled="disabled" :before-upload="beforeAvatarUpload" accept=".jpg, .png, .gif, .jpeg, .pdf" :file-list="fileList" > <i class="el-icon-plus"></i> <div slot="file" slot-scope="{ file }" v-loading="file.status == 'uploading'" style="height: 100%" > <pdf v-if="file.name.endsWith('.pdf')" :src="file.url" :page="1" ></pdf> <img v-else class="el-upload-list__item-thumbnail" style="object-fit: cover" :src="file.url" alt="" /> <spa class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)" > <i class="el-icon-zoom-in"></i> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)" > <i class="el-icon-delete"></i> </span> </spa> </div> </el-upload>
-
pdf预览,通过el-dialog 实现
<el-dialog title="查看PDF" :visible.sync="dialogVisible" width="80%" :modal="false" > <pdf ref="pdf" v-for="i in pdfPageNumber" :key="i" :src="pdfSrc" :page="i" ></pdf> </el-dialog>
-
图片预览,为了和项目图片预览保持统一,这里使用el-image自带的图片预览,不过需要自己手动调用
//设置一个1像素的,为了使用预览功能 <el-image ref="elImage" :src="previewImageUrl" style="width: 1px; height: 1px" :preview-src-list="[previewImageUrl]" ></el-image> //获取elImage元素,手动调用预览 let image = this.$refs.elImage; image.showViewer = true;
-
效果图
-
完整代码
<template>
<div>
<div style="display: flex; flex-direction: column">
<el-upload
ref="elUpload"
:action="baseUrl"
list-type="picture-card"
:limit="limit"
:class="{ hide: disabled }"
:disabled="disabled"
:before-upload="beforeAvatarUpload"
accept=".jpg, .png, .gif, .jpeg, .pdf"
:file-list="fileList"
>
<i class="el-icon-plus"></i>
<div
slot="file"
slot-scope="{ file }"
v-loading="file.status == 'uploading'"
style="height: 100%"
>
<pdf
v-if="file.name.endsWith('.pdf')"
:src="file.url"
:page="1"
></pdf>
<img
v-else
class="el-upload-list__item-thumbnail"
style="object-fit: cover"
:src="file.url"
alt=""
/>
<spa class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</spa>
</div>
</el-upload>
<p v-if="!disabled">
支持jpg、gif、png、pdf格式,最多上传10个,单个文件不超过20M。
</p>
<el-image
ref="elImage"
:src="previewImageUrl"
style="width: 1px; height: 1px"
:preview-src-list="[previewImageUrl]"
></el-image>
</div>
<el-image
ref="elImage"
:src="previewImageUrl"
style="width: 1px; height: 1px"
:preview-src-list="[previewImageUrl]"
></el-image>
<el-dialog
title="查看PDF"
:visible.sync="dialogVisible"
width="80%"
:modal="false"
>
<pdf
ref="pdf"
v-for="i in pdfPageNumber"
:key="i"
:src="pdfSrc"
:page="i"
></pdf>
</el-dialog>
</div>
</template>
<script>
import pdf from "vue-pdf";
export default {
name: "",
components: {
pdf,
},
props: {
///当前列表选中条目
selectRow: {
type: Object,
default: {},
},
//需要回显的文件
fileList: {
type: Array,
default: [],
},
//最大上传数
limit: {
type: Number,
default: 10,
},
///是否禁用上传,只支持放大预览
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
pdfPageNumber: 0,///pdf最页数
pdfSrc: "",///pdf地址
loadingBtn: false,
dialogVisible: false,
previewImageUrl: "",///预览图片都中
baseUrl: "",
};
},
mounted() {
this.getBaseUrl();
},
methods: {
///获取上传文件地址
getBaseUrl() {
if (process.env.NODE_ENV === "development") {
this.baseUrl =
"java/" +
this.$store.state.user.urlConfig["java"] +
"api/v1/app/aliyun/uploadFile";
} else {
this.baseUrl =
this.$store.state.user.urlConfig["java"] +
"api/v1/app/aliyun/uploadFile";
}
},
///判断文件大小
beforeAvatarUpload(file) {
const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) {
this.$message.error("上传头像图片大小不能超过 20MB!");
}
return isLt20M;
},
///点击删除
handleRemove(file) {
let uploadFiles = this.$refs.elUpload.uploadFiles;
let index = uploadFiles.findIndex((item) => {
return item == file;
});
uploadFiles.splice(index, 1);
},
///预览
handlePictureCardPreview(file) {
if (file.name.endsWith(".pdf")) {
if (file.response) {
this.pdfSrc = file.response.data;
} else {
this.pdfSrc = file.name;
}
this.getPDFnums(this.pdfSrc);
} else {
let image = this.$refs.elImage;
if (file.response) {
this.previewImageUrl = file.response.data;
} else {
this.previewImageUrl = file.name;
}
image.showViewer = true;
}
},
//计算pdf页码总数
getPDFnums(url) {
let loadURL = pdf.createLoadingTask({
url: url, //你的pdf地址
});
loadURL.promise.then((pdf) => {
this.pdfPageNumber = pdf.numPages;
this.dialogVisible = true;
});
},
getFileUrls() {
let fileNames = "";
const uploadFiles = this.$refs.elUpload.uploadFiles;
debugger
let uploading = uploadFiles.some((item) => {
return item.status == "uploading";
});
if (uploading) {
this.$message.warning("文件上传中,请稍后再试!");
return false;
}
uploadFiles.forEach((item) => {
const response = item.response;
if (response) {
if (response.code == 0) {
fileNames += response.data + ",";
}
} else {
fileNames += item.name + ",";
}
});
if (fileNames.endsWith(",")) {
fileNames = fileNames.replace(/,$/gi, "");
}
return fileNames;
},
},
};
</script>
<style lang='less' scoped>
/deep/ .hide .el-upload--picture-card {///deep 穿透隐藏上传图片入口
display: none;
}
</style>
PS:pdf有些发票信息显示不全,一些字体显示不出来,解决办法如下
//url 是当前pdf的链接地址
getPdfUrl(url) {
let src = pdf.createLoadingTask({
url: url,
//引入pdf.js字体,templ
cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/",
cMapPacked: true,
});
return src;
},
更多推荐
已为社区贡献3条内容
所有评论(0)