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

文章介绍了如何在Vue项目中使用vue-pdf组件展示PDF,特别是通过base64格式处理跨域问题。同时,文章提到了需要修改包内代码以解决错误,并详细阐述了如何使用patch-package创建补丁来保存这些修改。此外,还讨论了在遍历渲染多个PDF组件时可能出现的数据加载问题及其解决方案。
摘要由CSDN通过智能技术生成

使用

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
运行后,会多一个文件,在这里插入图片描述
这个里面会有添加的补丁内容,下次新增会在里面继续更新

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过vue-pdf实现PDF放大缩小功能,你可以使用vue-pdf的内置方法来控制PDF的缩放级别。以下是一个示例: 1. 首先,确保你已经安装了vue-pdf库。可以通过运行以下命令来安装它: ```shell npm install vue-pdf ``` 2. 在你的Vue组件中,导入vue-pdf库并注册它: ```vue <template> <div> <pdf :src="pdfSrc" :page="currentPage" @num-pages="setTotalPages" @page-loaded="setLoadedPages"></pdf> <button @click="zoomIn">放大</button> <button @click="zoomOut">缩小</button> </div> </template> <script> import { pdf } from 'vue-pdf'; export default { components: { pdf }, data() { return { pdfSrc: 'path_to_your_pdf_file.pdf', currentPage: 1, totalPages: 0, loadedPages: [], zoomLevel: 1 }; }, methods: { setTotalPages(totalPages) { this.totalPages = totalPages; }, setLoadedPages(loadedPages) { this.loadedPages = loadedPages; }, zoomIn() { this.zoomLevel += 0.1; this.$refs.pdf.setScale(this.zoomLevel); }, zoomOut() { this.zoomLevel -= 0.1; this.$refs.pdf.setScale(this.zoomLevel); } } }; </script> ``` 3. 在上面的示例中,我们在模板中添加了两个按钮,分别用于放大缩小。当按钮被点击时,我们调用相应的方法`zoomIn`和`zoomOut`。 4. 在`zoomIn`和`zoomOut`方法中,我们增加或减少`zoomLevel`变量的值,并通过`this.$refs.pdf.setScale`方法来设置PDF的缩放级别。`this.$refs.pdf`引用了vue-pdf组件的实例,我们可以通过它来访问vue-pdf提供的方法和属性。 这样,你就可以使用vue-pdf实现PDF放大缩小功能了。注意,这只是一个简单的示例,你可以根据需要进行调整和扩展。确保在vue-pdf组件上使用`ref`属性来获取组件的引用,以便在方法中使用它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值