开发者总是低估 PDF 查看器。看起来这就像一个简单的“文件展示”问题:获取字节流,将组件指向 URL,然后就大功告成了。Vue.js 让大部分 UI 工作都显得如此简单,但一个生产级别的 PDF 查看器却是那种会悄无声息地吞噬整个迭代周期的功能。我在两周内用四种不同的方式构建了同一个查看器。每一次尝试都印证了同一个观点:你周一选择的库,决定了你两个月后要在调试哪些 Bug。

过时教程的陷阱

大多数指南仍然推荐那些最后一次更新还在 Vue 2 时代的库。开发者扫一眼 README,运行安装命令,就以为最难的部分已经完成了。实际上,最难的部分才刚刚开始。你需要搜索功能。你需要在不导致浏览器标签页崩溃的情况下处理一份 400 页的政策文档。移动端用户会问为什么“捏合缩放”(pinch-to-zoom)感觉坏掉了。README 很少会警告你这些问题,因为演示 Demo 通常只渲染五页学术论文中的第一页。

四种方案

Vue 没有唯一的最佳 PDF 库。只有最适合你用户实际需求的库。

PDF.js:DIY 路径

Mozilla 的 PDF.js 是几乎所有基于 Web 的查看器底层的引擎。将其引入 Vue 3 应用并不意味着安装一个组件,而是意味着承担一个项目。你需要使用 getDocument 获取文档,将每一页渲染到 <canvas> 元素中,并将这些 canvas 连接到你的模板中。第一天,你会觉得效率很高。到了第三天,你就在配置 worker 脚本,使其能与 Vite 打包和 CORS 请求头和谐共处。

原生浏览器滚动在处理十页文档时表现良好,但在处理一千页时就会卡顿,因此你需要构建虚拟滚动。接着你会发现文本无法被选中,于是你不得不通过在每个 canvas 上方覆盖透明的文本 div 来解决。打印出来的效果很模糊,于是你开始研究 DPI 设置和媒体查询。移动端的捏合缩放会与浏览器的原生手势处理发生冲突。跨文档搜索意味着需要异步提取并索引每一页的文本,然后构建一个能在不阻塞主线程的情况下排队显示结果的 UI。即使使用像 Cursor 这样的 AI 编程助手来生成样板代码,你仍然需要掌控整个架构。难点并不会消失,它们只会迁移到你的代码库中。只有当你的需求非常特殊,或者你有数周的时间且有充分理由避免使用现成的行为时,这条路径才具有意义。

vue-pdf-embed:轻量化路径

有时你只需要展示文件。vue-pdf-embed 是一个 Vue 3 组件,它接受一个 source 并以垂直堆叠的方式渲染页面。安装和集成只需几分钟。对于显示生成的发票或合规报告的内部管理面板,这通常绰绰有余。该组件处理 canvas 渲染,用户可以进行滚动。

权衡之处在于其他一切。它没有工具栏,没有文档搜索,没有缩略图侧边栏,除了在滚动容器中翻阅之外,也没有页面导航。一旦利益相关者问:“我能搜索发票号码吗?”你两小时的集成工作就会膨胀成一个定制开发项目。当你的 PDF 很短、受众是内部人员且交互模式纯粹是只读滚动时,请选择它。

@tato30/vue-pdf:控制型路径

这个库从一个单体组件转变为一个组合式函数(composable)。它暴露了 usePDF,你可以在 setup 块中调用它。它不是渲染整个可滚动的文档,而是通过响应式 ref 一次管理一个页面。这听起来像是额外的工作,但当界面需要精确控制时,它会让你感到解脱。

想象一个保险理赔审核工具,理赔员核实一个文档页面,点击“下一步”,系统记录每次查看事件。连续滚动的查看器在这里是不合适的隐喻。你需要一个受控的分页器,也许带有直接绑定到当前页码的页面级评论或审批按钮。因为 usePDF 将页数和当前页作为响应式数据提供给你,将其连接到自定义导航栏或进度指示器会非常自然。你仍然需要构建 canvas 周围的 UI 外壳,但你避开了最底层的渲染样板代码。这适用于用户逐页查看而非快速浏览整份手稿的应用。

Vue PDF Viewer:全功能路径

当重新开发查看器功能开始分散你对核心产品的注意力时,转折点就到了。Vue PDF Viewer 是一款商业组件,自带完整的工具栏、文本搜索、注释、移动端响应式设计以及经过各种边缘情况测试的虚拟滚动功能。你的工作从“发明”变成了“配置”。你只需调整主题以匹配你的设计系统,开关所需的功能,然后就可以专注于那些真正能让你的应用脱颖而出的工作了。

前期的授权费用确实存在,但花费两周工程时间去重新实现搜索索引和注释层所带来的成本同样不容忽视。当你在紧迫的截止日期前交付生产级应用,且用户期望获得媲美桌面级 PDF 软件的体验时,这就是正确的工具。

安装的真实成本

最大的错误是将 npm install 命令视为总价。真正的成本在于安装完成后你所构建的内容。轻量级库在第一天很便宜,但当你发现需要搜索栏时,到了第 20 天就会变得昂贵。DIY 路径在第一天是免费的,但当你还在修复移动端触摸目标和打印样式表时,到了第 60 天就会变得昂贵。商业路径需要前期投入资金,但它可以为你节省数周的工程时间,让你能将精力投入到实际的业务逻辑中。

不要仅仅因为一个库的 README 短小精悍且友好就选择它。要根据你的项目需求来选择。如果需要缩略图侧边栏、文本搜索和客户端注释,那么你应该选择全功能解决方案。如果只是在内部仪表板中进行快速的小票预览,那么轻量级嵌入式方案更合适。

核心总结

在决定使用任何 Vue PDF 库之前,请准确写下你的用户需要执行的操作。如果他们只是需要滚动浏览短文档,vue-pdf-embed 就能满足需求。如果他们在受控的工作流中逐页查看,请选择 @tato30/vue-pdf。如果他们在关乎业务核心的应用中进行注释、搜索和打印,请购买商业查看器。如果你的需求确实非常独特,但时间表比较灵活,那就预留出几周时间,直接基于 PDF.js 进行构建。PDF 查看器绝不仅仅是一个简单的文件组件。它是一个完整的文档交互界面,而你选择的构建模块将决定你是本月交付,还是推迟到下个季度。