Vue 3 实战:从零到一用 vue-pdf-embed 打造功能齐全的 PDF 查看器

你好,Vue 开发者们!

在 Web 开发中,我们经常会遇到需要在页面中直接展示 PDF 文件的需求,例如预览合同、显示报告或在线阅读文档。你可能会想到用 <iframe> 或者一些重量级的库,但它们往往不够灵活或过于臃肿。

今天,我将向你介绍一个轻量、强大且对 Vue 3 非常友好的解决方案——vue-pdf-embed

🤔 vue-pdf-embed 是什么?

vue-pdf-embed 是一个专门为 Vue 设计的 PDF 查看器组件。它基于 Mozilla 的 PDF.js,但去除了所有不必要的 UI 和复杂性,只专注于提供一个纯粹、高性能的 PDF 渲染核心。

核心亮点:

  • 📦 轻量级:只包含渲染 PDF 所需的核心逻辑,打包体积小。
  • 🖼️ 高质量渲染:利用 PDF.js,确保 PDF 内容清晰、准确地显示。
  • 📱 响应式:能够很好地适应不同尺寸的容器。
  • 🔧 高度可控:通过 Props 和事件,你可以完全控制 PDF 的渲染行为,如页码、缩放、旋转等。
  • ✨ Vue 3 兼容:完美支持 Vue 3 的组合式 API 和 <script setup> 语法。

🛠️ 安装

将 vue-pdf-embed 添加到你的项目中非常简单:

npm install vue-pdf-embed

🚀 快速上手:三分钟渲染你的第一个 PDF

集成 vue-pdf-embed 只需要几行代码。

1. 引入组件

<script setup>
import VuePdfEmbed from "vue-pdf-embed";
</script>

2. 在模板中使用

你需要提供一个 source 属性,指向你的 PDF 文件。它可以是一个 URL、Base64 字符串或 ArrayBuffer。

<template><VuePdfEmbedsource="https://raw.githubusercontent.com/mozilla/pdf.js/master/web/compressed.tracemonkey-pldi-09.pdf"/>
</template>

就这样!一个 PDF 查看器已经成功渲染在你的页面上了。是不是超级简单?


✨ 进阶实战:打造一个功能齐全的 PDF 查看器

当然,仅仅显示 PDF 是不够的。我们通常需要分页、缩放等功能。下面,我们将创建一个更完整的 PDF 查看器组件。

核心思路

  1. 加载 PDF:监听 @loaded 事件,在 PDF 加载完成后获取总页数。
  2. 分页控制:创建“上一页”和“下一页”按钮,通过修改 page prop 来切换页面。
  3. 缩放控制:创建“放大”和“缩小”按钮,通过修改 scale prop 来调整视图大小。
  4. 状态显示:显示当前页码和总页数。

完整代码示例 (PdfViewer.vue)

<template><div class="pdf-viewer-container"><!-- 控制栏 --><div class="controls"><button @click="prevPage" :disabled="page <= 1">上一页</button><span>第 {{ page }} / {{ pageCount }} 页</span><button @click="nextPage" :disabled="page >= pageCount">下一页</button><button @click="zoomOut" :disabled="scale <= 0.5">缩小</button><span>缩放: {{ Math.round(scale * 100) }}%</span><button @click="zoomIn" :disabled="scale >= 2">放大</button></div><!-- PDF 渲染区域 --><div class="pdf-wrapper"><VuePdfEmbedref="pdfRef":source="pdfSource":page="page":scale="scale"@loaded="handleDocumentLoaded"@rendering-failed="handleRenderingFailed"/></div></div>
</template><script setup>
import { ref, watch } from "vue";
import VuePdfEmbed from "vue-pdf-embed";// PDF 文件源
const pdfSource = ref("https://raw.githubusercontent.com/mozilla/pdf.js/master/web/compressed.tracemonkey-pldi-09.pdf"
);// PDF 组件引用
const pdfRef = ref(null);// PDF 状态
const page = ref(1);
const pageCount = ref(0);
const scale = ref(1);// PDF 加载完成回调
function handleDocumentLoaded(pdf) {console.log("PDF 加载完成!", pdf);pageCount.value = pdf.numPages;
}// PDF 渲染失败回调
function handleRenderingFailed(error) {console.error("PDF 渲染失败:", error);
}// 分页功能
function prevPage() {if (page.value > 1) {page.value--;}
}function nextPage() {if (page.value < pageCount.value) {page.value++;}
}// 缩放功能
function zoomIn() {if (scale.value < 2) {scale.value += 0.25;}
}function zoomOut() {if (scale.value > 0.5) {scale.value -= 0.25;}
}// 监听页码变化,确保在范围内
watch(page, (newPage) => {if (newPage < 1) {page.value = 1;}if (newPage > pageCount.value && pageCount.value > 0) {page.value = pageCount.value;}
});
</script><style scoped>
.pdf-viewer-container {max-width: 900px;margin: 2rem auto;border: 1px solid #ccc;border-radius: 8px;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}.controls {display: flex;justify-content: center;align-items: center;gap: 1rem;padding: 1rem;background-color: #f5f5f5;border-bottom: 1px solid #ccc;border-radius: 8px 8px 0 0;
}.controls button {padding: 0.5rem 1rem;border: 1px solid #ddd;border-radius: 4px;background-color: #fff;cursor: pointer;
}.controls button:disabled {cursor: not-allowed;opacity: 0.5;
}.controls span {font-size: 0.9rem;min-width: 100px;text-align: center;
}.pdf-wrapper {height: 70vh;overflow: auto;background-color: #e9e9e9;padding: 1rem;
}/* vue-pdf-embed 的内部样式,我们可以覆盖它 */
:deep(.vue-pdf-embed > div) {margin-bottom: 8px;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
</style>

常用 Props 和事件

  • Props:
  • source: PDF 文件来源 (URL, Base64, Uint8Array, …)。
  • page: (Number) 要显示的页码。
  • scale: (Number) 缩放比例。
  • rotation: (Number) 旋转角度 (0, 90, 180, 270)。
  • width: (Number | String) 容器宽度。
  • height: (Number | String) 容器高度。
  • Events:
  • @loaded: PDF 文档加载完成时触发,回调参数为 PDF.js 的文档对象,可以从中获取总页数 numPages 等信息。
  • @rendered: 所有可见页面渲染完成时触发。
  • @rendering-failed: 渲染失败时触发。
  • @password-requested: 当 PDF 需要密码时触发。

总结

vue-pdf-embed 为在 Vue 应用中嵌入 PDF 提供了一个极其简单而又强大的解决方案。它避免了 <iframe> 的笨重和同源策略问题,也比一些重量级 UI 库更轻量、更灵活。

通过组合其 Props 和事件,你可以轻松构建出符合业务需求的、交互丰富的 PDF 查看器。如果你正在寻找一个可靠的 Vue PDF 渲染方案,vue-pdf-embed 绝对是你的不二之选。

 Vue 3 实战:从零到一用 vue-pdf-embed 打造功能齐全的 PDF 查看器 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿技术分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96186.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96186.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

adb的常用命令

adb devices 用USB数据线连接电脑&#xff0c;查看连接上的设备 adb tcpip 5555 切换计算机的adb为wifi连接模式 adb connect 192.168.2.250:5555 连接手机的ip地址&#xff0c;如果连接成功&#xff0c;则可拔掉数据线 adb 查看adb的相关信息&#xff0c;包括版本号&#xff0…

稳态太阳光模拟器 | 多源分布式设计的要点有哪些?

稳态太阳模拟器的多源分布式设计&#xff0c;是一种通过多组独立光源单元分布式排布、结合稳态光学调控技术&#xff0c;实现对太阳光谱、辐照强度及辐照均匀性精准复现的高端光模拟技术。其核心优势在于突破传统模拟光源在长期工作稳定性、大面积辐照均匀性及能量传递效率上的…

代码随想录 day 35 动态规划

第九章 动态规划part03 正式开始背包问题&#xff0c;背包问题还是挺难的&#xff0c;虽然大家可能看了很多背包问题模板代码&#xff0c;感觉挺简单&#xff0c;但基本理解的都不够深入。 如果是直接从来没听过背包问题&#xff0c;可以先看文字讲解慢慢了解 这是干什么的。 …

大数据探索性分析——抽样技术应用

2.3 概率抽样 一、简单随机抽样 # 数据预处理 LoanStats3c read.csv("D:/OneDrive - stu.fynu.edu.cn/大四上学期/ysq-大数据探索性分析/data/2数据集二&#xff1a;Loan Data--Lending Club/LoanStats3c/LoanStats3c.csv", header TRUE, fill TRUE, comment.char…

20 webUI应用中Controlnet精讲(06)-结构理解与其它

前面的篇章已经详细讲解了线条约束、三维关系与空间深度、人体姿态等几类controlnet的功能与应用&#xff0c;本节内容将对通过controlnet对图像的结构理解及控图效果。 序号 分类 Controlnet名称 备注 1 线条约束 Canny&#xff08;硬边缘&#xff09; 约束性强&#x…

【MFC】对话框属性:Center(居中)

前言 本文介绍对话框属性中的Center(居中)&#xff0c;同时给出相关示例便于理解。 目录1 位置2 详解3 示例1 位置 首先介绍一下这个属性在哪里。 在资源视图中双击对话框节点&#xff0c;打开该对话框&#xff1b; 鼠标右键工作区空白处&#xff0c;单击属性&#xff1b; 此时…

SciKit-Learn 全面分析分类任务 breast_cancer 数据集

背景 乳腺癌数据集&#xff0c;569个样本&#xff0c;30个特征&#xff0c;2个类别&#xff08;良性/恶性&#xff09; 步骤 加载数据集拆分训练集、测试集数据预处理&#xff08;标准化&#xff09;选择模型模型训练&#xff08;拟合&#xff09;测试模型效果评估模型 分析方法…

【开题答辩全过程】以 _基于SpringBoot技术的“树洞”心理咨询服务平台的设计与实现为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

R 语法高亮为什么没有,是需要安装专用的编辑软件,R语言自带的R-gui 功能还是比较简单

R 语法高亮为什么没有&#xff0c;是需要安装专用的编辑软件&#xff0c;R语言自带的R-gui 功能还是比较简单 以下是一些主流的 R 编辑软件&#xff08;IDE / 编辑器&#xff09;&#xff0c;适用于不同需求的用户&#xff1a; ✅ 最推荐&#xff1a;RStudio&#xff08;免费/…

使用UniApp实现下拉框和表格组件页面

使用UniApp实现下拉框和表格组件页面UniApp提供了一套完整的跨平台开发框架&#xff0c;支持在多个平台上运行。下拉框和表格是常见的UI组件&#xff0c;可以通过UniApp内置组件或第三方插件实现。下拉框组件的实现UniApp内置的<picker>组件可以实现下拉选择功能。以下是…

JavaScript 对象说明

JavaScript 对象说明 1. 对象的基本概念 在 JavaScript 中&#xff0c;对象是一种复合数据类型&#xff0c;用于存储相关联的属性和方法。对象可以看作是属性的集合&#xff0c;其中每个属性都由一个键&#xff08;key&#xff09;和一个值&#xff08;value&#xff09;组成。…

【竞赛系列】机器学习实操项目04——客户信用评估模型开发全流程(baseline)

上一章&#xff1a;机器学习实操项目03——Scikit-learn介绍及简单分类案例 下一章&#xff1a; 机器学习核心知识点目录&#xff1a;机器学习核心知识点目录 机器学习实战项目目录&#xff1a;【从 0 到 1 落地】机器学习实操项目目录&#xff1a;覆盖入门到进阶&#xff0c;大…

C++中的单例模式的实现

1 什么是单例模式单例模式 是一种创建型设计模式&#xff0c;确保一个类在整个程序生命周期中只有一个实例&#xff0c;并提供一个全局访问点。核心要求&#xff1a;类不能被外部随意创建&#xff08;禁止 public 构造函数或限制实例数量&#xff09;。不能被复制或移动。提供一…

汇编基础1

1.格式伪操作&#xff1a;它们不是ARM处理器实际的指令&#xff08;如MOV&#xff0c; ADD等&#xff09;&#xff0c;而是写给汇编器看的命令&#xff0c;用于指导汇编器如何工作area reset, code, readonlycode32entry内容 endarea: 这是最重要的一个伪操作&#xff0c;用…

设计模式(C++)详解—单例模式(2)

<摘要> 单例模式是创建型设计模式中最简单但应用最广泛的模式之一&#xff0c;它确保一个类只有一个实例并提供全局访问点。本文从历史背景和核心概念出发&#xff0c;系统阐述了单例模式的产生缘由和演进脉络&#xff0c;深入剖析了其在资源管理、状态一致性和访问控制方…

kafka如何保证消息的顺序性

kafka如何保证消息的顺序性 Kafka只能在分区&#xff08;Partition&#xff09;级别保证消息的顺序性&#xff0c;而不能在主题&#xff08;Topic&#xff09;级别保证全局顺序。 核心原理&#xff1a;分区和偏移量分区&#xff08;Partition&#xff09;是顺序性的基础&#x…

传输层:UDP/TCP协议

网络协议图 一.UDP 特点: 无连接&#xff0c;不可靠&#xff0c;面向数据报&#xff0c;全双工&#xff08;前面网络编程中介绍过&#xff09; 格式: 服务器的端口号一般都是程序员指定的(这样你才能访问到),客户端的端口号是系统自动分配的(如果提前指定好, 可能会与其他程…

A/B测试全解析:原理、流程与实战案例

A/B测试&#xff08;AB Testing&#xff09;原理与实践全解析 在数据驱动的时代&#xff0c;A/B测试几乎是每一个互联网公司都会使用的实验方法。无论是电商平台优化转化率&#xff0c;还是内容平台提升点击率&#xff0c;抑或是游戏公司提升留存&#xff0c;A/B测试都是最常见…

循环神经网络(三):小练习

RNN小练习 要求&#xff1a; 假设有 4 个字 吃 了 没 &#xff1f;&#xff0c;请使用 torch.nn.RNN 完成以下任务 将每个进行 one-hot 编码请使用 吃 了 没 作为输入序列&#xff0c;了 没 &#xff1f; 作为输出序列RNN 的 hidden_size 64请将 RNN 的输出使用全连接转换成 4…

ESPIDF官方文档,启用dhcp会禁用对应的STA或AP的静态IP,我测试STA确实是,但是AP不是,为什么

1. STA 模式下的 DHCP&#xff08;客户端角色&#xff09;ESP32 当 Station&#xff08;STA&#xff09; 时&#xff0c;它的行为就跟你的手机/笔记本连 Wi-Fi 一样&#xff1a;DHCP 客户端 → 去路由器&#xff08;DHCP 服务器&#xff09;要一个 IP。特点启用 DHCP&#xff0…