【Vue】vue3.2でpdf.jsを使って穴を踏む:privateフィールドから読み込めない---pdf.js詳細解説

vue3.2プロジェクトで++を使用しており、pdf.js ライブラリviteを使用して pdf ファイルを読み込んでプレビューする予定ですts本当に不快です!! !

1.pdf.js をインストールする

Sao Rui、バージョンは気にしないで、cnpmだけで終わりです

cnpm i pdfjs-dist

ここに画像の説明を挿入

2.ピットを踏む

導入後、コンソールはエラーを報告し、エラーの内容の翻訳は次のとおりです。
Cannot read from private fieldプライベート変数を読み取ることができません。

Cannot read from private field

pdfDoc.getPage調査の結果、ここに問題があります:
vue3 のプロキシに関するもので、

  • Vue2 はデータの変更を監視し、defineProperty を介して読み取ります。
  • Vue3 はプロキシ経由でデータを変更します。

ただし、pdfjs-dist のソース コードでは、インターセプト チェックが行われます.チェックの内容は、現在渡されているパラメーター、obj オブジェクトがあるかどうか、ない場合はプライベート変数を読み取れないというエラーがスローされます。直接。以前の古いプロジェクトでは、このように書いても問題ありません: pdfjs-dist がインターセプトしてチェックすると、MaskXXX のオブジェクトになります (この名前で呼ばれているようです)。vue3 では、pdfjs-dist が検証をインターセプトすると、プロキシ オブジェクトを取得します。

正解: pdfDoc.getPage の pdfDoc はレスポンシブ ライティングを使用しないでください。! !

こちらの記事を参照してください: https://www.jianshu.com/p/1432ccd5089a

以下は正しい書き方です (コードは少し乱雑で、後でコンポーネント形式に変更されます。表示はテストと説明のためだけです)。

<template>
	<div class="usinghelp-container">
		<div class="pdf-view">
        <canvas :id="`pdfCanvas${page}`" v-for="page in state.pdfPages" :key="page"></canvas>
	    </div>
	    <div class="pdf-bottom">我是操作区域</div>
	</div>
</template>

<script lang="ts" setup name="usinghelp">
import {
      
       reactive, onMounted, nextTick } from 'vue';
import {
      
       ElMessage } from 'element-plus';
import * as PDF from "pdfjs-dist";
import workerSrc from "pdfjs-dist/build/pdf.worker.entry.js"; // 引入时如果报红线错误,不影响运行, 或在index.d.ts中声明declare

const state = reactive<any>({
      
      
    pdfPath: "/pdf/华康医疗公司简介.pdf", //本地PDF文件路径放在/public中
    pdfPages: '', // 页数
    pdfWidth: "", // 宽度
    pdfSrc: "", // 地址
    pdfScale: 1.0, // 放大倍数
});

// 此处为正确写法---原来我的参数用的响应式写法,就会报错Cannot read from private field
let pdfDoc:any = ""; // 文档内容---必须使用非响应式存储


// 页面加载时
onMounted(() => {
      
      
	initTableData();
});

// 初始化表格数据
const initTableData = () => {
      
      
  PDF.GlobalWorkerOptions.workerSrc = workerSrc;
  console.log("开始 pDF测试");
  console.log(workerSrc);
  console.log(PDF);
  console.log("结束");
  loadFile(state.pdfPath);
};

// 加载pdf文件
const loadFile = (url: string) => {
      
      
    let loadingTask = PDF.getDocument(url);
    loadingTask.promise.then((pdf: any) => {
      
      
      console.log('PDF loaded');
      debugger
      pdfDoc = pdf;
      state.pdfPages = pdf.numPages;
      nextTick(() => {
      
      
          renderPage(1); // 表示渲染第 1 页
      });
    });
}

// 渲染指定页面的内容
const renderPage = (num: number) => {
      
      
  console.log('PDF 开始渲染',num);
  console.log(pdfDoc);
  pdfDoc.getPage(num).then((page: any) => {
      
      
    console.log('Page loaded');
    let canvas:any = document.getElementById(`pdfCanvas${ 
        num}`);
    let ctx = canvas.getContext("2d");
    let dpr = window.devicePixelRatio || 1;
    let bsr =
        ctx.webkitBackingStorePixelRatio ||
        ctx.mozBackingStorePixelRatio ||
        ctx.msBackingStorePixelRatio ||
        ctx.oBackingStorePixelRatio ||
        ctx.backingStorePixelRatio ||
        1;
    let ratio = dpr / bsr;
    let viewport = page.getViewport({
      
       scale: state.pdfScale });
    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    // canvas.style.width = viewport.width + "px";
    // canvas.style.height = viewport.height + "px";
    canvas.style.width = "100%";
    canvas.style.height = "100%";
    state.pdfWidth = viewport.width + "px";
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
    // 将 PDF 页面渲染到 canvas 上下文中
    let renderContext = {
      
      
        canvasContext: ctx,
        viewport: viewport,
    };
    page.render(renderContext);
    if (state.pdfPages > num) {
      
      
        renderPage(num + 1);
    }
  });
}
</script>

<style lang="scss" scoped>
.usinghelp-container{
      
      
  .pdf-view {
      
      
    width: 80vw;
    height: 80vh;
    margin: 0 auto;
    border: 1px solid #f90;
    overflow: auto;
  }
}
</style>

おすすめ

転載: blog.csdn.net/weixin_42960907/article/details/127366807