vue-pdf的使用,及遇到的坑和问题,使用拖动、滚轮放大缩小、旋转图片查看图片/pdf,使用patch-package更改依赖包内容

使用

vue-pdf中,使用base64文件格式实现展示,或者路径直接展示的方法,为包增加补丁使用patch-package

首先下载包
yarn安装

yarn install vue-pdf

npm安装

npm install --save vue-pdf

项目实际使用

<!--## 关于使用PreviewPdf组件-->
<!-- - 需要将node_modules >> vue-pdf >> src >> pdfjsWrapper.js文件中第196-198行改为-->
<!--pdfRender.cancel();这是因为报错问题,下面讲怎么设置补丁,其他人更包也可以直接使用-->
<template>
  <div class="TopClass">
    <div class="preview-pdf-wrapper" ref="handlePicture">
      <div class="preview-pdf" ref="handleImg"  @wheel="handleWheel" @mousedown="handleMousedown" @dblclick="magnify">
        <pdf :src="path" :page="page" :rotate="rotate" @num-pages="pagesCount"></pdf>
      </div>
    </div>
  </div>
</template>

<script>
import pdf from 'vue-pdf' // 这是pdf的引入
import CMapReaderFactory from 'vue-pdf/src/CMapReaderFactory.js'  //这个引入是因为pdf汉字可能乱码,需要引入这个

export default {
    
    
  name: 'PreviewPdf',
  components: {
    
     pdf },
  props: {
    
    
    src: {
    
     type: String },
    showsection: {
    
     type: Boolean, default: false },
    pathurl: {
    
     type: String },
    RefDate:{
    
    type: String }
  },
  data() {
    
    
    return {
    
    
      // src: '../../../static/pdf/111.pdf', // 如果是本地引入,一定要放在public下面,不然可能加载不出来
      path: '',
      page: 1,
      pageCount: 0,
      rotate: 0,
      dragging: false,
      lastLeft: 0,
      lastTop: 0,
      parentWidth: null,
      parentHeight: null,
    }
  },
  created() {
    
    
    this.pdfData()
  },
  mounted() {
    
    
    this.$nextTick(() => {
    
    
      const {
    
     width: parentWidth, height: parentHeight } = this.$refs.handlePicture.getBoundingClientRect()
      this.parentWidth = parentWidth
      this.parentHeight = parentHeight
      this.dragDialog()
    })
  },
  methods: {
    
    
    magnify(){
    
    
      window.open(this.pathurl) //这是为了预览大图使用,就是在浏览器直接打卡,赋值路径就可以了可以后端返,也可以使用base64下面的方法转后,直接把path给它
    },
    // 赋值给页面转base64
    pdfData() {
    
    
      let datas = `data:application/pdf;base64,${
      
      this.src}` // 这是因为项目中遇到跨域,需要使用base64格式来展示,所以这样做,如果项目不涉及跨域,直接用下面这个就可以了,传路径就可以出来了
      // this.path = pdf.createLoadingTask({ url: datas, CMapReaderFactory });
      pdf.createLoadingTask(datas, {
    
     CMapReaderFactory }).promise.then(pdf => {
    
     this.path = pdf.loadingTask })
    },
    pagesCount($event) {
    
    
      this.pageCount = $event
    },
    //pdf翻页上一页
    changePage(type) {
    
    
      this.resetSize()
      this.rotate = 0
      if (type === 'prev' && this.page > 1) {
    
    
        this.page -= 1
      } else if (type === 'next' && this.page < this.pageCount) {
    
    
        this.page += 1
      }
    },
    // 左右旋转使用
    rotateRight(type){
    
    
      if (type === 'L' ) {
    
    
        this.rotate -= 90
      } else if (type === 'R' ) {
    
    
        this.rotate += 90
      }
    },
    //旋转
    rotatePDF() {
    
    
      this.rotate += 90
    },
    //放大缩小
    handleWheel(e) {
    
    
      if(this.showsection !== true) return
      e.preventDefault()
      let el = e.currentTarget
      let delta = (e.wheelDelta && (e.wheelDelta > 0 ? 1 : -1))

      if (delta > 0) {
    
    //放大
        // 向上滚
        let oWidth = el.offsetWidth//取得图片的实际宽度
        let oHeight = el.offsetHeight //取得图片的实际高度

        el.style.width = (oWidth + 50) + 'px'
        el.style.height = (oHeight + 50 / oWidth * oHeight) + 'px'

      } else if (delta < 0) {
    
    //缩小
        //向下滚
        let oWidth = el.offsetWidth //取得图片的实际宽度
        let oHeight = el.offsetHeight //取得图片的实际高度
        if (el.offsetLeft < 0 || el.offsetTop < 0) {
    
    
          this.$refs.handleImg.style.left = 0
          this.$refs.handleImg.style.top = 0
        }
        if (el.offsetWidth > this.parentWidth || el.offsetHeight > this.parentHeight) {
    
    //判断如果图片缩小到原图大小就停止缩小(不能小于包裹它的父元素的宽高)
          el.style.width = oWidth - 50 + 'px'
          el.style.height = oHeight - 50 / oWidth * oHeight + 'px'
        }
      }
    },
    //还原尺寸
    resetSize() {
    
    
      this.$refs.handleImg.style.minwidth = '100%'
      this.$refs.handleImg.style.minheight = '100%'
      this.$refs.handleImg.style.left = 0
      this.$refs.handleImg.style.top = 0
    },
    //鼠标在图片上落下,可拖动
    handleMousedown($event) {
    
    
      if(this.showsection !== true) return
      $event.preventDefault()
      this.lastLeft = $event.clientX
      this.lastTop = $event.clientY
      this.dragging = true
    },
    //拖动
    startDragging(e) {
    
    
      if (this.dragging) {
    
     this.calculateDragging(e) }
    },
    //停止拖动
    stopDrag() {
    
    
      this.dragging = false
    },
    dragDialog() {
    
    
      document.addEventListener('mousemove', this.startDragging)
      document.addEventListener('mouseup', this.stopDrag)
    },
    calculateDragging(e) {
    
    
      let deltaX = e.clientX - this.lastLeft
      let deltaY = e.clientY - this.lastTop
      const {
    
     offsetLeft, offsetTop } = this.$refs.handleImg
      let resultX = this.calculateBeyond('x', offsetLeft + deltaX)
      let resultY = this.calculateBeyond('y', offsetTop + deltaY)
      this.$refs.handleImg.style.left = resultX + 'px'
      this.$refs.handleImg.style.top = resultY + 'px'
      this.lastLeft = e.clientX
      this.lastTop = e.clientY
    },
    calculateBeyond(type, result) {
    
    
      const {
    
     width, height } = this.$refs.handleImg.getBoundingClientRect()
      if (type === 'x') {
    
    
        if (width <= this.parentWidth) return  //仅当图片宽度超出父级元素的宽度时才能被拖动
        if (result < -(width - this.parentWidth)) {
    
    
          return -(width - this.parentWidth)
        } else if (result > 0) {
    
    
          return 0
        } else {
    
    
          return result
        }
      } else if (type === 'y') {
    
    
        if (height <= this.parentHeight) return //仅当图片高度超出父级元素的高度时才能被拖动
        if (result < -(height - this.parentHeight)) {
    
    
          return -(height - this.parentHeight)
        } else if (result > 0) {
    
    
          return 0
        } else {
    
    
          return result
        }
      }
    }
  },
}
</script>

<style scoped lang='scss'>
.TopClass {
    
    
  width: 100%;
  height: 100%;

  .preview-pdf-wrapper {
    
    
    width: 100%;
    height: 98%;
    position: relative;
    overflow: hidden;

    .preview-pdf {
    
    
      min-width: 100%;
      min-height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      transition: transform 0.25s linear;
    }
  }

  .btnclass {
    
    
    position: absolute;
    height: 100%;
    right: 20px;

    .BtnClass {
    
    
      display: flex;
      justify-content: flex-end;
      .el-button {
    
    
        margin: 5px;
      }
    }
  }

}</style>

遇到的问题

1、使用中,有遇到包内保存,最上面已经写了怎么解决,找到包
将这里的内容修改
在这里插入图片描述

2、循环遍历出来的组件,在使用中,一定要将vue-pdf组件销毁注释掉,如果组件没有加载完成,pdf.createLoadingTask不会出数据
在这里插入图片描述
3、在多个pdf文件渲染中,出现一个问题,出现有数据无法加载,渲染的问题,好像是pdf使用的promise给数据,数据没有取到,就会出现这种情况,单个的pdf组件没有出现这个问题,但是我是使用的多个遍历出来的,所以遇到问题有点坑,最后是使用的这个解决
获取到再赋值,这样就不会拿不到了

pdf.createLoadingTask(datas, {
    
     CMapReaderFactory }).promise.then(pdf => {
    
     this.path = pdf.loadingTask })

patch-package的使用

npm安装

npm i patch-package

yarn安装

// v1.x:
yarn add patch-package postinstall-postinstall
// v2.x
yarn patch

在文件中,找到package.json加入

"postinstall": "patch-package"

在这里插入图片描述
修改了node_modules内的依赖后,运行一下命令

npm patch-package +包名

如npm patch-package vue-pdf

yarn patch-package +包名

如yarn patch-package vue-pdf
运行后,会多一个文件,在这里插入图片描述
这个里面会有添加的补丁内容,下次新增会在里面继续更新

猜你喜欢

转载自blog.csdn.net/qq_41180882/article/details/130017032