vue+element在线浏览文件轮播组件(支持pdf/doc/
2020-03-11 本文已影响0人
七號7777
看自己用的框架选择,vue+iview查看器可以参考这篇文章https://www.jianshu.com/p/32cd865a8b34
效果图
微信截图_20200310161707.png
首先PDF为了提高兼容性,我们可以加载一个原生的PDF插件(pdf.js)
插件下载地址:http://mozilla.github.io/pdf.js/getting_started/
点击蓝色按钮的下载就行
在vue项目下的static添加一个pdf文件夹,放入以下得到的两个文件夹,
image.png
在vue项目下的static添加一个jpgView文件夹,放入这两个文件
viewer.js 和 viewer.css(下载路径:https://www.jianshu.com/p/8ffdbe48859e)
安装base64转换插件:
npm install js-base64 --save
写个组件页面(el-carousel自己找文档看参数,还有doc文档查看的话只能查看外网的,内网的文件看不了(一般现在分内外网开发,想测试效果的话,可以在正式服务器扔一份文件看效果))
<template>
<div>
<el-carousel
:id="viewerId"
:autoplay='false'
v-if="fileUrls !== undefined && fileUrls.length>0"
@change="changeIndex">
<el-carousel-item v-for="(item) in PTFurls" :key="item.id">
<div style="text-align: center;height: 100%;">
<iframe
scrolling="auto"
:src="item.url"
class="scrollStyle table_120_list"
frameborder="0"
width="100%"
height="100%"
:id="item.id"
@load="cardFinish($event,item.id,'pdf')"
>
该浏览器暂不支持PDF浏览,您可以下载该文件进行查看:
<a :src="item.url" rel="external nofollow">下载PDF文件</a>
</iframe>
<Spin size="large" fix v-if="item.loading"></Spin>
</div>
</el-carousel-item>
<el-carousel-item v-for="(item,index) in DOCurls" :key="index+100">
<div style="text-align: center;height: 100%;">
<iframe
scrolling="auto"
:src="'http://view.officeapps.live.com/op/view.aspx?src='+item.url"
class="scrollStyle table_120_list"
frameborder="0"
width="100%"
height="100%"
>
该浏览器暂不支持文档浏览,您可以下载该文件进行查看:
<a :src="item.url" rel="external nofollow">下载文档文件</a>
</iframe>
</div>
</el-carousel-item>
<el-carousel-item v-for="(item) in Imgurls" :key="item.id">
<div style="text-align: center;height: 100%;">
<img
:src="item.url"
style="height:85%;cursor: pointer;width: 100%"
alt="点击查看"
title="点击查看"
@click="imgShow(viewerId)"
/>
<div style="margin-top: 10px;text-align: center;">
<el-button type="primary" @click="plaintiffDown(item.url)" plain>下载到电脑</el-button>
</div>
</div>
</el-carousel-item>
</el-carousel>
<div v-else style="height:500px;text-align: center;margin-top: 50px;width: 100%">暂无数据</div>
</div>
</template>
<script>
import '@static/viewer/viewer.css'
import Viewer from '@static/viewer/viewer'
import { urlRedirect } from '@/libs/address'
export default {
name: 'ZhViewer',
props: {
fileUrls: {
type: Array,
default: function () {
return []
}
},
viewerId: {
type: String
}
},
data () {
return {
setting: {
dots: 'outside',
radiusDot: true
},
nowIndex: 0, // 当前显示第几张
allHost: urlRedirect(), // 域名
PTFurls: [], // PTF文件
Imgurls: [], // IMG文件
DOCurls: [] // DOC文件
}
},
methods: {
changeIndex (index) {
this.nowIndex = index
},
imgShow (name) {
// 放在模态框的有时候会出现第一次图片放大显示在模态框下面,所以加个层级
let gallery = new Viewer(document.getElementById(name), {
show: function () {
gallery.update()
},
hide: function() {
gallery.destroy() // 图片点击放大后关闭图片时销毁
},
zIndex: 9999
})
gallery.show()
},
init () {
// console.log(this.fileUrls)
},
plaintiffDown (item) {
// 必须同源才能下载
// var alink = document.createElement('a')
// alink.href = item
// let type = item.split('.')[1]
// let name = item.split('.')[0]
// alink.download = name + '.' + type // 图片名
// alink.click()
// 以上注释掉的部分,是会在同个页面上替换链接打开图片,我们的需求是开新页面,所以我用了window.open()
window.open(item)
},
cardFinish (e, id, type) {
// 判断iframe是否加载完毕
switch (type) {
case 'pdf':
this.PTFurls.forEach((item, index) => {
if (item.id === id) {
item.loading = false
this.$set(item, 'loading', false)
}
})
break
}
setTimeout(() => {
this.nowIndex = 0
}, 2000)
},
spinShow () {
return false
}
},
mounted () {
// console.log(this.fileUrls)
},
watch: {
fileUrls: {
immediate: true,
handler (val) {
// 当前域名
this.allHost = `${urlRedirect()}/` --------------------------自己的域名自己配
this.PTFurls = []
this.DOCurls = []
this.Imgurls = []
// console.log('fileUrls', this.fileUrls)
// 筛选文件分别显示
this.fileUrls.forEach((item, index) => {
let fileType = item.path.split('.')[item.path.split('.').length - 1] // 获取文件类型
let url = item.path.indexOf('http://') >= 0 ? item.path : this.allHost + item.path // 过滤文件路径
let time = Date.parse(new Date())
switch (fileType) {
case 'pdf':
this.PTFurls.push({
url: url + '?' + time,
loading: false,
id: item.id
})
break
case 'xlsx':
case 'docx':
this.DOCurls.push({
url: url + '?' + time,
loading: true,
id: Math.random()
.toString(36)
.substr(2)
})
break
case 'jpg':
case 'png':
case 'jpeg':
this.Imgurls.push({
url: url + '?' + time,
loading: true,
id: item.id
})
break
}
})
// this.nowIndex = this.fileUrls.length - 1
this.nowIndex = 0
}
},
// 当前轮播的下标 ------------外部删除或者添加操作的时候会用到
nowIndex: {
immediate: true,
handler (newVal, oldVal) {
this.$emit('emitNowIndex', newVal)
}
}
}
}
</script>
引入组件,注册组件,引用组件
import moreFileViewer from '@/components/fileViewer/moreFileViewer.vue'// 路径自己放,这里只是例子
components: { moreFileViewer }
// v-if = 'modal' ---是因为我放在模态框里面,一个页面上有多个数据有引入该插件,然后切换的时候根据外部标签的显示隐藏,不然第一份打开正常后,第二份点击图片放大的时候图片不显示,具体看自己的效果,有遇到的话可以根据外部标签的显示隐藏做改变
// fileUrls 绑定的数组,里面的对象是{path: '链接'},记住是path字段,只要传的数组里面的对象包含path就行,或者不想叫path,上面组件代码自己改
// viewerId 大家都知道,id是唯一的,所以这个加随机数,或者你们加下标什么都没问题,只要确保不重复就行
// emitNowIndex 获取当前展示的轮播图的下标
<more-file-viewer v-if='modal' :fileUrls='viewArr' :viewerId="'one'+Math.floor(Math.random() * 10000)" @emitNowIndex="emitNowIndex"></more-file-viewer>
// 当前展示的文件
emitNowIndex (index) {
this.nowIndex = index
},