🔥 用 Vue2 + PDF.js 手撸一个「PDF 连续预览器」,自适应屏幕、支持缩放,直接拿来用!

🌈 前言

最近做项目,产品丢过来一个需求: "我们要一个像掘金文章那样的 PDF 连续预览功能,要自适应屏幕,还要支持放大缩小!"

我心想,这需求简单啊,直接搜一波现成的库,结果一看,要么太重,要么不支持连续预览,要么缩放体验差,要么样式丑。

于是,干脆自己撸一个!用 Vue2 + PDF.js ,花了一个下午,效果还不错,直接分享给大家,代码已经整理好了,复制粘贴就能用!

🚀 效果展示

  • ✅ 支持 PDF 文件上传预览
  • 连续滚动 显示所有页面,像浏览网页一样
  • 自适应屏幕宽度,窗口大小变化自动调整
  • 支持缩放(放大、缩小、重置)
  • 加载进度提示,体验更友好
  • 样式美观,代码简洁易读

📦 技术栈

  • Vue2:熟悉的响应式框架
  • PDF.js:Mozilla 出品的 PDF 渲染库,功能强大
  • FontAwesome:图标库,让按钮更美观

🛠️ 核心实现思路

1. 引入依赖

js 复制代码
<!-- Vue2 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- PDF.js -->
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js"></script>
<!-- FontAwesome -->
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

2. 文件上传

使用 <input type="file" accept=".pdf"> 实现文件选择,通过 FileReader 读取文件内容:

jshandleFileUpload(e) 复制代码
  const file = e.target.files[0];
  if (!file || file.type !== 'application/pdf') {
    this.errorMessage = '请上传PDF格式的文件';
    return;
  }

  const fileReader = new FileReader();
  fileReader.onload = (event) => {
    const typedArray = new Uint8Array(event.target.result);
    this.loadPdf(typedArray);
  };
  fileReader.readAsArrayBuffer(file);
}

3. 渲染 PDF 页面

使用 PDF.js 的 getDocument 方法加载 PDF,然后逐页渲染:

js 复制代码
renderPage(pageNum, containerWidth) {
  this.pdfDoc.getPage(pageNum).then(page => {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');

    // 计算缩放比例,自适应容器宽度
    const viewport = page.getViewport({ scale: 1 });
    const baseScale = Math.min(containerWidth / viewport.width, 2);
    const scale = baseScale * this.zoom;
    const scaledViewport = page.getViewport({ scale });

    canvas.height = scaledViewport.height;
    canvas.width = scaledViewport.width;

    const renderContext = {
      canvasContext: context,
      viewport: scaledViewport
    };

    page.render(renderContext).promise.then(() => {
      this.loadedPages++;
    });
  });
}

4. 缩放功能

通过调整 zoom 值,重新渲染所有页面:

js 复制代码
zoomIn() {
  if (this.zoom < 3) {
    this.zoom += 0.1;
    this.reRenderAllPages();
  }
},
zoomOut() {
  if (this.zoom > 0.3) {
    this.zoom -= 0.1;
    this.reRenderAllPages();
  }
},
resetZoom() {
  this.zoom = 1.0;
  this.reRenderAllPages();
}

5. 自适应屏幕

监听窗口大小变化,自动重新渲染:

js 复制代码
mounted() {
  window.addEventListener('resize', () => {
    if (this.pdfDoc && this.showViewer) {
      this.reRenderAllPages();
    }
  });
}

📝 使用方式

  1. 复制文章开头提供的完整 HTML 代码
  2. 保存为 index.html
  3. 直接双击打开即可使用

🏁 结语

一个简单的 PDF 连续预览器就完成了,代码不到 300 行,功能却很实用。如果你有更好的想法或者遇到问题,欢迎在评论区留言交流!

相关推荐
顾安r5 小时前
11.8 脚本网页 星际逃生
c语言·前端·javascript·flask
Hello.Reader5 小时前
Data Sink定义、参数与可落地示例
java·前端·网络
im_AMBER6 小时前
React 17
前端·javascript·笔记·学习·react.js·前端框架
一雨方知深秋6 小时前
2.fs模块对计算机硬盘进行读写操作(Promise进行封装)
javascript·node.js·promise·v8·cpython
谷歌开发者7 小时前
Web 开发指向标 | Chrome 开发者工具学习资源 (六)
前端·chrome·学习
一晌小贪欢7 小时前
【Html模板】电商运营可视化大屏模板 Excel存储 + 一键导出(已上线-可预览)
前端·数据分析·html·excel·数据看板·电商大屏·大屏看板
发现你走远了7 小时前
连接模拟器网页进行h5的调试(使用Chrome远程调试(推荐)) 保姆级图文
前端·chrome
街尾杂货店&8 小时前
css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
前端·css
顺凡8 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
小白路过8 小时前
CSS transform矩阵变换全面解析
前端·css·矩阵