需求
展示图片和PDF类型,并且点击图片或者PDF可以预览
第一步:遍历所有的图片和PDF列表
<div v-for="(data,index) in parerFont(item.fileInfo)" :key="index" class="data-list-item">
<downloadCard :file-info="data" />
</div>
第二步:编写downloadcard组件
<template>
<div class="download-card">
<!-- 图片与PDF格式 -->
<file-preview v-if="isImageOrPDF(fileInfo.url)" :url="fileInfo.url" :name="fileInfo.name" />
<!-- ZIP XSLS WAP 等格式 -->
<div v-else class="other-type">
<div><d2-icon-svg name="transaction" class="iconrefresh" /></div>
<div class="file-name-other">{{ fileInfo.name }}</div>
</div>
<div @click="donwload(fileInfo.url, fileInfo.name)">
<d2-icon name="import" class="iconimport" />
</div>
</div>
</template>
<script>
import axios from 'axios';
import FilePreview from '@/components/file-preview';
export default {
name: 'downloadCard',
components: {
FilePreview
},
props: {
fileInfo: {
type: Object,
default: () => {}
}
},
data() {
return {
};
},
created() {
},
methods: {
justPDF(str) {
var strRegex = '(.pdf)$'; // 用于验证后缀是否是pdf
var reg = new RegExp(strRegex);
if (reg.test(str.toLowerCase())) {
// console.log('是pdf')
return true;
} else {
// console.log('不是pdf')
return false;
}
},
isImageOrPDF(filename) {
// 获取文件的扩展名
const extension = filename.split('.').pop().toLowerCase();
// 常见的图片和 PDF 文件扩展名
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
const pdfExtensions = ['pdf'];
// 检查文件扩展名是否在常见图片或 PDF 扩展名列表中
return imageExtensions.includes(extension) || pdfExtensions.includes(extension);
},
donwload(fileUrl, fileName = '') {
axios({
method: 'get',
url: fileUrl,
responseType: 'blob',
}).then((response) => {
const link = document.createElement('a');
const blob = new Blob([response.data], { type: response.data.type });
const urlRef = window.URL.createObjectURL(blob);
link.href = urlRef;
link.download = fileName;
link.click();
window.URL.revokeObjectURL(urlRef);
}).catch(err => {
console.log(err);
});
}
}
};
</script>
<style scoped lang="scss">
.download-card{
padding: 12px;
border-radius: 12px;
border: 1px dashed rgba(234, 234, 234, 1);
box-sizing: border-box;
background: rgba(255, 255, 255, 1);
display: flex;
align-items: center;
width: 235px;
justify-content: space-between;
color: rgba(114, 120, 128, 1);
.file-name{
width: 136px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
}
.file-name-other{
width: 160px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
margin-left: 5px;
}
.type-img{
display: flex;
}
.type-pdf{
display: flex;
}
.iconrefresh, .iconimport{
width: 24px !important;
height: 24px !important;
}
.other-type{
display: flex;
align-items: center;
cursor: default;
}
}
</style>
第三步:编写FilePreview实现图片和PDF预览组件
<template>
<div class="preview-wrap">
<!-- PDF和图片类型点击 -->
<div v-if="justPDF(url)" class="type-pdf" @click="previewFile(url)">
<div><d2-icon-svg name="transaction" class="iconrefresh" /></div>
<div class="file-name-pdf">{{ name }}</div>
</div>
<div v-else class="type-img" @click="previewFile(url)">
<div>
<img :src="url" class="type-img-preview" alt="">
</div>
<div class="file-name">{{ name }}</div>
<div class="hover-pick">
<img src="../../../public/image/merchant/Magnifying_glass.png" class="type-img-innner" alt="">
</div>
</div>
<!-- PDF预览 -->
<template v-if="pdfContainerVisible">
<div id="pdf-container" />
<div class="pdf-close" @click="pdfContainerVisible = false">
<i class="el-icon-close" />
</div>
</template>
<!-- 图片预览 -->
<viewer
v-else
:options="{'toolbar': false, 'navbar': false, 'title': false}"
:images="[url]"
@inited="imagePreviewInited">
<template slot-scope="scope">
<img v-for="(src, index) in scope.images" :src="src" :key="index" style="display:none;">
</template>
</viewer>
</div>
</template>
<script>
import Viewer from 'v-viewer/src/component.vue';
import 'viewerjs/dist/viewer.css';
// import MagnifyingGlass from '../../../public/image/merchant/Magnifying_glass.png';
import local from './local';
const SCOPE_NAME = 'siPreview';
export default {
name: SCOPE_NAME,
components: {
Viewer,
},
inheritAttrs: false,
props: {
url: {
type: String,
default: '',
},
name: {
type: String,
default: '',
},
isImageBase64: false,
},
data() {
return {
pdfContainerVisible: false,
};
},
created() {
if (!this.$i18n.getLocaleMessage('en')[SCOPE_NAME]) {
this.$i18n.mergeLocaleMessage('en', local.en);
this.$i18n.mergeLocaleMessage('cn', local.cn);
}
},
methods: {
justPDF(str) {
var strRegex = '(.pdf)$'; // 用于验证后缀是否是pdf
var reg = new RegExp(strRegex);
if (reg.test(str.toLowerCase())) {
// console.log('是pdf')
return true;
} else {
// console.log('不是pdf')
return false;
}
},
// 文件预览
previewFile(fileUrl) {
const fileExtension = fileUrl.split('.').pop();
const isPdf = fileExtension.toLowerCase().startsWith('pdf');
const isImg = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].find(suffix => fileExtension.toLowerCase().startsWith(suffix));
if (isPdf) {
this.pdfPreview(fileUrl);
} else if (isImg || this.isImageBase64) {
this.imagePreview();
} else {
window.open(fileUrl);
}
},
// 图片预览
imagePreview() {
this.$viewer.show();
},
imagePreviewInited(viewer) {
this.$viewer = viewer;
},
// PDG预览
pdfPreview(fileUrl) {
this.pdfContainerVisible = true;
this.$nextTick(() => {
let url = '';
if (fileUrl.startsWith('http://')) {
url = fileUrl.substring(5);
} else if (fileUrl.startsWith('https://')) {
url = fileUrl.substring(6);
} else {
url = fileUrl;
}
// eslint-disable-next-line no-undef
PDFObject.embed(url, '#pdf-container', {
width: '80%'
});
});
}
},
};
</script>
<style lang="scss" scoped>
.preview-wrap {
display: inline-block;
width: 224px;
// background: red;
height: 30px;
margin-right: 5px;
}
.preview-button {
padding: 0;
}
#pdf-container {
position: fixed;
z-index: 10000;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
background-color: rgba(0, 0, 0, 0.6);
}
.pdf-close {
position: fixed;
z-index: 10001;
right: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
font-size: 40px;
color: #fff;
background-color: rgba(0, 0, 0, 0.4);
cursor: pointer;
}
.file-name{
width: 136px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
margin-left: 5px;
}
.file-name-pdf{
width: 156px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
margin-left: 5px;
}
.hover-pick{
position: absolute;
top: 0;
background: #000;
margin-top: -6px;
border-radius: 8px;
width: 42px;
height: 42px;
border: none;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
opacity: 0.5;
visibility: hidden;
}
.type-img{
display: flex;
height: 30px;
align-items: center;
position: relative;
.type-img-preview{
height: 40px;
width:40px;
object-fit: cover;
margin-right: 5px;
margin-top: 3px;
border-radius: 8px;
border: 1px solid #EAEAEA;
}
.type-img-innner{
height: 15px;
width:15px;
z-index: 2;
}
&:hover{
.hover-pick{
visibility:visible;
}
}
}
.type-pdf{
display: flex;
height: 30px;
align-items: center;
}
.iconrefresh{
width: 24px !important;
height: 24px !important;
}
</style>