Vue 3 中使用 vue - pdf - embed + vue3 - pdfjs 在线预览 PDF

news/2025/3/20 9:34:54/

在许多 Web 应用程序中,需要实现 PDF 文件的在线预览功能。Vue 3 作为流行的前端框架,配合 vue - pdf - embed 和 vue3 - pdfjs 库,可以轻松实现这一需求。本文将详细介绍如何在 Vue 3 项目中使用这两个库进行 PDF 在线预览。

 完整代码实现及演示效果请参考开源项目:vue3-pc-template

一、环境准备

确保你已经创建了一个 Vue 3 项目,并且安装了相关依赖。如果没有安装 vue - pdf - embed 和 vue3 - pdfjs,可以通过以下命令进行安装:

npm install vue - pdf - embed vue3 - pdfjs

二、代码实现

(一)父组件中使用

javascript"><template><div class="pdf-container"><PDFView :pdfUrl="jsPdf" /></div></template><script setup>import PDFView from "@/components/PdfPreview/index.vue";import jsPdf from "/pdf/test.pdf"; // 本地地址// const jsPdf = 'http://localhost/test.pdf' // 线上地址也可,但需要注意跨域问题</script><style scoped>.pdf-container {overflow: auto;}</style>
1、 template部分

在<template>中,创建了一个div容器,类名为pdf - container,用于包裹 PDF 预览组件PDFView。并通过:pdfUrl属性将jsPdf传递给子组件PDFView。

2、 script部分

引入PDFView组件,同时定义了jsPdf变量,它可以是本地 PDF 文件路径(如/pdf/test.pdf),也可以是线上地址(但要注意跨域问题)。

3、 style部分

pdf - container添加overflow: auto样式,以便在内容超出容器大小时出现滚动条。

(二)将实现逻辑封装成子组件

@/components/PdfPreview/index.vue
javascript"><template><div class="pdf-preview"><div id="page - view" :style="{position: 'absolute',top: '50%',left: '50%',transform: `translate(-50%, -50%) scale(${state.scale})`,width: '100%',height: `${pageHeight}`,}"><vue - pdf - embed :source="state.source" :page="state.pageNum" textLayer /></div></div><div class="page - tool"><div class="page - tool - item" @click="lastPage">上一页</div><div class="page - tool - item" @click="nextPage">下一页</div><div class="page - tool - item">{{ state.pageNum }}/{{ state.numPages }}</div><div class="page - tool - item" @click="pageZoomOut">放大</div><div class="page - tool - item" @click="pageZoomIn">缩小</div></div></template><script setup lang="ts">import { reactive, onMounted, ref } from "vue";import VuePdfEmbed from "vue - pdf - embed";import { createLoadingTask } from "vue3 - pdfjs";const props = defineProps({pdfUrl: {type: String,required: true,},});const pageHeight = ref('100%');const state = reactive({source: props.pdfUrl, //预览pdf文件地址pageNum: 1, //当前页面scale: 1, // 缩放比例numPages: 0, // 总页数});function lastPage() {if (state.pageNum > 1) {state.pageNum -= 1;}}function nextPage() {if (state.pageNum < state.numPages) {state.pageNum += 1;}}function pageZoomOut() {if (state.scale < 2) {state.scale += 0.1;pageHeight.value = (parseInt(pageHeight.value) - 5.0) + '%';}}function pageZoomIn() {if (state.scale > 1) {state.scale -= 0.1;pageHeight.value = (parseInt(pageHeight.value) + 5.0) + '%';}}onMounted(() => {const loadingTask = createLoadingTask(state.source);loadingTask.promise.then((pdf: { numPages: number }) => {state.numPages = pdf.numPages;});});</script><style lang="css" scoped>.pdf-preview {position: relative;height: 100vh;padding: 20px 0;box-sizing: border-box;background-color: e9e9e9;}.pdf-wrap {overflow-y: auto;}.vue - pdf - embed {text-align: center;width: 515px;border: 1px solid #e5e5e5;margin: 0 auto;box-sizing: border-box;}.page - tool {position: absolute;bottom: 35px;padding-left: 15px;padding-right: 15px;display: flex;align-items: center;background: rgb(66, 66, 66);color: white;border-radius: 19px;z-index: 100;cursor: pointer;margin-left: 50%;transform: translateX(-50%);}.page - tool - item {padding: 8px 15px;padding-left: 10px;cursor: pointer;}</style>
1、 template部分
  • 创建了一个div容器,类名为pdf - preview,作为整体的预览区域,设置了相对定位和一些基本样式。
  • pdf - preview内部,有一个div,id为page - view,通过:style绑定动态样式,实现居中显示和缩放效果。在这个div内部,使用vue - pdf - embed组件,通过:source属性传递 PDF 文件地址,:page属性传递当前显示的页码,并启用textLayer。
  • 下方还有一个div,类名为page - tool,用于显示页面切换和缩放的工具按钮。每个按钮通过@click绑定相应的方法。
2、 script部分
  • 引入 Vue 的reactive、onMounted、ref等函数,以及vue - pdf - embed和vue3 - pdfjs中的createLoadingTask。
  • 通过defineProps定义接收父组件传递的pdfUrl属性,并且设置为必填。
  • 使用ref定义pageHeight变量,初始值为100%,用于控制预览区域的高度。
  • 使用reactive定义state对象,包含source(PDF 文件地址)、pageNum(当前页码)、scale(缩放比例)、numPages(总页数)等属性。
  • 定义了lastPage、nextPage、pageZoomOut、pageZoomIn等方法,分别用于上一页、下一页、放大、缩小的功能实现。
  • 在onMounted钩子函数中,通过createLoadingTask创建加载任务,获取 PDF 文件的总页数并更新state.numPages。
3、 样式部分
  • pdf - preview设置背景色、高度、内边距等样式。
  • 给vue - pdf - embed设置居中显示、边框、宽度等样式。
  • 给page - tool设置绝对定位、背景色、圆角、水平居中对齐等样式,给page - tool - item设置内边距和鼠标指针样式。

三、注意事项

1、 跨域问题

如果使用线上地址,需要确保服务器端设置了正确的跨域策略,否则会出现跨域请求失败的问题。可以通过在服务器端配置 CORS(跨域资源共享)来解决。

2、 文件路径

确保本地 PDF 文件路径正确,并且在打包和部署时,文件能够正确被访问到。

完整代码实现请参考开源项目:vue3-pc-template

欢迎 Star 和 Fork 项目,一起构建更完善的权限管理体系!


http://www.ppmy.cn/news/1580565.html

相关文章

npm error gyp info

在使用 npm 安装 Node.js 包时&#xff0c;可能会遇到各种错误&#xff0c;其中 gyp 错误是比较常见的一种。gyp 是 Node.js 的一个工具&#xff0c;用于编译 C 代码。这些错误通常发生在需要编译原生模块的 npm 包时。下面是一些常见的原因和解决方法&#xff1a; 常见原因及…

【免费】怎么将MP4转换为GIF,如何在线实现多媒体文件格式互转

目录 【免费】怎么将MP4转换为GIF&#xff0c;如何在线实现多媒体文件格式互转 小瓜有话说 一、多媒体格式转换在线网站 1、在线网站 2、convertio实践 3、ezgif实践 二、使用桌面软件 1、GIMP&#xff08;免费简单&#xff09; 2、Adobe Photoshop 三、使用命令行工…

算法系列——有监督学习——1.线性回归

一、背景 1. 学习参数&#xff1a; 直线可写为yw0w1*x。这是一次函数&#xff0c;w1是斜率&#xff08;或者叫权重 &#xff09;&#xff0c;w0相当于在y轴上的截距。斜率w1和截距w0是由有监督学习的算法学到的参数&#xff0c;称之为学习参数。在线性回归中&#xff0c;需要…

3.1 在VisionPro脚本中添加CogGraphicLabel

本案例需要实现如下功能&#xff1a; 1.加载toolBlock 2.加载图片&#xff0c; 3.运行Block 4.VisionPro中添加脚本显示数值。 见下图&#xff1a;详细代码&#xff08;C#以及visionPro&#xff09;见下面链接&#xff1a; https://download.csdn.net/download/qq_340474…

OpenManus:无需邀请码的开源版Manus,开启自动化新纪元

对于那些渴望拥有自己的AI助手但苦于无法获取Manus邀请码的用户来说,OpenManus提供了一个绝佳的选择。这款开源项目不仅复刻了Manus的核心功能,还允许用户在自己的电脑上执行包括网页浏览、文件操作和代码编写在内的多种任务。本文将详细介绍OpenManus的功能及其使用方法。 …

Netty基础—6.Netty实现RPC服务二

大纲 1.RPC的相关概念 2.RPC服务调用端动态代理实现 3.Netty客户端之RPC远程调用过程分析 4.RPC网络通信中的编码解码器 5.Netty服务端之RPC服务提供端的处理 6.RPC服务调用端实现超时功能 3.Netty客户端之RPC远程调用过程分析 NettyRpcClient.remoteCall()方法的执行逻…

【JavaEE】-- SpringBoot快速上手

文章目录 1. Maven1.1 什么是Maven1.2 为什么要学Maven1.3 创建一个Maven项目1.4 Maven核心功能1.4.1 项目创建1.4.2 依赖管理1.4.3 Maven Help插件 1.5 Maven仓库1.5.1 本地仓库1.5.2 中央仓库1.5.3 私有服务器&#xff08;私服&#xff09; 1.6 Maven设置国内源1.6.1 配置当前…

sqlite mmap

https://www.sqlite.org/mmap.html 1. 内存映射 I/O 的基本原理 默认机制&#xff08;传统 I/O&#xff09; SQLite 默认通过 xRead() 和 xWrite() 方法&#xff08;对应 read()/write() 系统调用&#xff09;访问数据库文件。这些方法需要将数据从内核缓冲区复制到用户空间&am…