当前位置: 首页 > news >正文

使用 Vue + PDF.js 构建在线 PDF 阅读器(支持目录与缩放)

文章目录

  • 一、项目简介
  • 二、项目结构
  • 三、PDF.js 引入与使用
    • 3.1 安装依赖
    • 3.2 初始化 PDF.js Worker
  • 四、核心组件开发:PdfViewer.vue
    • 4.1 组件模板结构
    • 4.2 组件逻辑功能
    • 4.3 样式样例
  • 五、目录大纲支持(可选拓展)
  • 六、组件使用方式
  • 七、常见问题与优化建议
    • 7.1 跨域问题
    • 7.2 大文件性能优化
  • 八、总结

一、项目简介

本项目使用 Vue 3 搭配 PDF.js 构建一个支持目录、页面缩放和页码跳转的 PDF 在线阅读器组件,适用于后台管理系统、在线文档平台、电子书阅读等场景。

核心功能包括:

  • 支持加载远程 PDF 文件
  • 页面跳转与缩放控制
  • 渲染页码与总页数
  • 目录大纲展示
  • 自适应页面宽度

二、项目结构

使用以下目录结构组织组件与逻辑:

项目根目录
src
assets
components
views
App.vue
main.js
PdfViewer.vue
Home.vue

三、PDF.js 引入与使用

3.1 安装依赖

npm install pdfjs-dist

3.2 初始化 PDF.js Worker

// src/utils/pdfWorker.js
import * as pdfjsLib from 'pdfjs-dist';
import pdfWorker from 'pdfjs-dist/build/pdf.worker.entry';

pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker;

export default pdfjsLib;

四、核心组件开发:PdfViewer.vue

4.1 组件模板结构

<template>
  <div class="pdf-container">
    <div class="pdf-controls">
      <button @click="prevPage">上一页</button>
      <span>{{ currentPage }} / {{ totalPages }}</span>
      <button @click="nextPage">下一页</button>
      <select v-model="scale">
        <option v-for="s in [0.5, 1, 1.5, 2]" :key="s" :value="s">缩放 {{ s }}x</option>
      </select>
    </div>
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

4.2 组件逻辑功能

// src/components/PdfViewer.vue
<script setup>
import { ref, onMounted, watch } from 'vue';
import pdfjsLib from '@/utils/pdfWorker';

const props = defineProps({
  pdfUrl: String
});

const pdfDoc = ref(null);
const currentPage = ref(1);
const totalPages = ref(0);
const scale = ref(1);
const canvasRef = ref(null);

const renderPage = async (pageNum) => {
  const page = await pdfDoc.value.getPage(pageNum);
  const viewport = page.getViewport({ scale: scale.value });
  const canvas = canvasRef.value;
  const context = canvas.getContext('2d');

  canvas.height = viewport.height;
  canvas.width = viewport.width;

  const renderContext = {
    canvasContext: context,
    viewport: viewport
  };
  await page.render(renderContext).promise;
};

const loadPdf = async () => {
  const loadingTask = pdfjsLib.getDocument(props.pdfUrl);
  pdfDoc.value = await loadingTask.promise;
  totalPages.value = pdfDoc.value.numPages;
  renderPage(currentPage.value);
};

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++;
  }
};

const prevPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--;
  }
};

watch([currentPage, scale], () => {
  renderPage(currentPage.value);
});

onMounted(() => {
  loadPdf();
});
</script>

4.3 样式样例

<style scoped>
.pdf-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.pdf-controls {
  margin-bottom: 1rem;
}
canvas {
  border: 1px solid #ddd;
}
</style>

五、目录大纲支持(可选拓展)

你可以通过 getOutline() 获取 PDF 的目录并展示:

const outline = await pdfDoc.value.getOutline();

outline.forEach(item => {
  console.log('章节标题:', item.title);
});

你可以进一步将其渲染为嵌套列表,实现目录跳转功能。


六、组件使用方式

在页面中使用组件:

<template>
  <PdfViewer pdfUrl="/test.pdf" />
</template>

<script setup>
import PdfViewer from '@/components/PdfViewer.vue';
</script>

七、常见问题与优化建议

7.1 跨域问题

远程 PDF 地址若跨域未配置,需服务端支持 CORS 或改为本地代理加载。

7.2 大文件性能优化

  • 延迟加载页码(分页懒加载)
  • 限制初始渲染页
  • 使用虚拟滚动加载多页内容

八、总结

通过整合 Vue 3 与 PDF.js,我们实现了一个功能完备、用户体验良好的在线 PDF 阅读器。它具备高度的可扩展性,你可以根据业务继续扩展目录跳转、批注、签名、下载等功能,打造属于你的文档系统。


到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕

在这里插入图片描述

http://www.dtcms.com/a/123003.html

相关文章:

  • Petalinux最简开发
  • (2)网络学习之堡垒机
  • 如何避免Python爬虫重复抓取相同页面?
  • 【数据结构】树状数组
  • RTT中断管理学习
  • 苹果电脑MAC系统安装
  • 【MySQL篇】mysqlpump和mysqldump参数区别总汇
  • 【C++游戏引擎开发】第11篇:GLFW、GLAD环境搭建与第一个三角形渲染
  • 09-Spring 与线程安全:IOC 与多线程下的坑与解法
  • 解锁Midjourney创作潜能:超详细提示词(Prompts)分类指南
  • 【42期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深指数最新分时BOLL数据及接口API说明文档
  • 三、使用Keil5新建STM32工程
  • 【学Rust写CAD】29 Alpha256结构体(alpha256.rs)
  • torch.meshgrid()
  • 【OCR】总结目前流行的主要的OCR工具
  • Jenkins安装流程
  • 联邦学习研读笔记
  • printf
  • 【NLP 面经 9、逐层分解Transformer】
  • 第十一章 Python语言-高阶技巧(终章)
  • Dubbo(44)如何排查Dubbo的服务依赖问题?
  • 17. git pull
  • 6、nRF52xx蓝牙学习(nrf_gpiote.c库函数学习)
  • 基于 AI智能体、大模型、RAG、Agent 等技术构建公司内部闭环智能问答系统的详细方案,结合 Spring Boot + Vue 管理系统 的改造思路
  • Http代理服务器选型与搭建
  • Starrocks的Bitmap索引和Bloom filter索引以及全局字典
  • 基于微信小程序的志愿服务系统的设计与实现
  • 数字图像处理作业3
  • fuse-python使用fuse来挂载fs
  • 汽车软件开发常用的建模工具汇总