🌈 前言
最近做项目,产品丢过来一个需求: "我们要一个像掘金文章那样的 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();
}
});
}
📝 使用方式
- 复制文章开头提供的完整 HTML 代码
- 保存为
index.html
- 直接双击打开即可使用
🏁 结语
一个简单的 PDF 连续预览器就完成了,代码不到 300 行,功能却很实用。如果你有更好的想法或者遇到问题,欢迎在评论区留言交流!