美文网首页
vue+element在线浏览文件轮播组件(支持pdf/doc/

vue+element在线浏览文件轮播组件(支持pdf/doc/

作者: 七號7777 | 来源:发表于2020-03-11 15:46 被阅读0次

    看自己用的框架选择,vue+iview查看器可以参考这篇文章https://www.jianshu.com/p/32cd865a8b34

    效果图


    微信截图_20200310161707.png

    首先PDF为了提高兼容性,我们可以加载一个原生的PDF插件(pdf.js)
    插件下载地址:http://mozilla.github.io/pdf.js/getting_started/
    点击蓝色按钮的下载就行

    image.png
    在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
    },
    

    相关文章

      网友评论

          本文标题:vue+element在线浏览文件轮播组件(支持pdf/doc/

          本文链接:https://www.haomeiwen.com/subject/vtxgdhtx.html