Vue3项目中使用本地pdf.js分发文件夹的配置与目录结构方案
问题说明
我在Vue3项目中使用纯pdf.js展示PDF文件,禁止使用任何Vue PDF预览库。当前需要完成两个目标:
- 调整项目目录结构,适配本地引入pdf.js官方的distribution文件夹
- 将当前使用的cdnjs在线链接替换成本地的distribution文件
以下是我基于pdf.js官方示例实现的现有代码和目录结构:
当前实现代码
pdf-view.vue
<template> <canvas :id="`the-canvas${index}`" style="border: 1px solid"></canvas> </template> <script setup> import { onMounted, defineProps } from 'vue' const { file, index } = defineProps(['file', 'index']) onMounted(() => { import('https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.mjs').then((pdfjsLib) => { pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.mjs' if (!file) return const fileReader = new FileReader() fileReader.onload = () => { const array = new Uint8Array(fileReader.result) const loadingTask = pdfjsLib.getDocument(array) loadingTask.promise.then( (pdf) => { const pageNumber = 1 pdf.getPage(pageNumber).then((page) => { const scale = 1.5 const viewport = page.getViewport({ scale }) const canvas = document.getElementById(`the-canvas${index}`) const context = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width // 渲染PDF页面到canvas上下文 const renderContext = { canvasContext: context, viewport: viewport } page.render(renderContext) }) }, (reason) => { // PDF加载错误 console.error(reason) } ) } fileReader.readAsArrayBuffer(file) }) }) </script> <style> </style>
parent.vue
<template v-for="(file, index) in pdfFiles" :key="file"> <pdfview :file="file.file" :index="index" /> </template> <script setup> import pdfview from '@/components/pdf-view/pdf-view.vue' </script>
当前目录结构
--Project -public -src --components ---pdf-view ----pdf-view.vue [组件] --views ----parent.vue [组件]
解决方案
1. 调整目录结构
从pdf.js官方下载最新的distribution压缩包,解压后将核心文件放到项目public目录下的单独文件夹中(建议命名为pdfjs),最终目录结构如下:
--Project -public --pdfjs -pdf.mjs -pdf.worker.mjs -src --components ---pdf-view ----pdf-view.vue --views ----parent.vue
2. 修改pdf-view.vue代码
将在线引入替换成本地文件,同时调整worker路径:
<template> <canvas :id="`the-canvas${index}`" style="border: 1px solid"></canvas> </template> <script setup> import { onMounted, defineProps } from 'vue' const { file, index } = defineProps(['file', 'index']) onMounted(() => { // 引入本地pdf.mjs import('/pdfjs/pdf.mjs').then((pdfjsLib) => { // 设置本地worker路径 pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs/pdf.worker.mjs' if (!file) return const fileReader = new FileReader() fileReader.onload = () => { const array = new Uint8Array(fileReader.result) const loadingTask = pdfjsLib.getDocument(array) loadingTask.promise.then( (pdf) => { const pageNumber = 1 pdf.getPage(pageNumber).then((page) => { const scale = 1.5 const viewport = page.getViewport({ scale }) const canvas = document.getElementById(`the-canvas${index}`) const context = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width // 渲染PDF页面到canvas上下文 const renderContext = { canvasContext: context, viewport: viewport } page.render(renderContext) }) }, (reason) => { // PDF加载错误 console.error(reason) } ) } fileReader.readAsArrayBuffer(file) }) }) </script> <style> </style>
3. 额外优化建议
- 若需要多页渲染,可在
pdf-view.vue中添加页码控制逻辑,循环调用pdf.getPage(pageNumber)渲染每页内容 - 可将pdf.js的初始化逻辑封装成独立工具函数,避免组件代码冗余
- 注意:
public目录下的文件会直接复制到构建后的根目录,因此路径使用绝对路径/pdfjs/xxx即可
内容的提问来源于stack exchange,提问作者Nixit Ahir
相关产品推荐
相关产品推荐

