vue3中预览pdf,给出完整代码
时间: 2025-06-16 17:25:37 浏览: 19
<think>我们正在处理一个关于Vue3中实现PDF预览的请求。用户需要完整的代码示例。根据之前的上下文,我们有一个关于Vue2实现PDF预览的引用,但用户现在需要Vue3的版本。在Vue3中,我们可以使用类似的库,但需要注意Vue3的CompositionAPI和组件注册方式的不同。我们将使用`vue3-pdf`或者`pdfvuer`?但注意,`vue-pdf`库主要针对Vue2,而Vue3可能需要使用其他库。实际上,有一个名为`vue3-pdfjs`的库,或者我们可以使用原生的PDF.js,但为了快速实现,我们可以使用`pdfjs-dist`库并结合Vue3的响应式特性。不过,经过搜索,有一个比较流行的库是`vue-pdf-embed`,它支持Vue3。但这里为了提供完整示例,我们选择使用`pdfjs-dist`,因为它是PDF.js的官方分发版本,并且可以独立于任何框架使用,这样更通用。但是用户要求完整代码示例,因此我们需要一个具体的、可运行的例子。考虑到易用性和流行度,我们可以使用`vue-pdf-embed`,因为它专为Vue3设计。首先,我们需要安装它。步骤:1.安装依赖:`npminstallvue-pdf-embed`2.在组件中引入并使用。然而,为了确保示例的完整性,我们将提供一个使用`vue-pdf-embed`的简单组件。如果用户没有特别指定,我们也可以考虑使用`pdfvuer`,它同时支持Vue2和Vue3。但根据npm页面,`vue-pdf-embed`更轻量且专为Vue3设计。因此,我们决定使用`vue-pdf-embed`。示例代码:我们将创建一个名为`PdfPreview.vue`的组件。注意:这个组件需要传递`pdfSource`作为PDF文件的路径或URL。另外,我们还需要处理分页和旋转等功能。下面是一个基本的示例:</think>### Vue3 实现 PDF 预览完整代码示例
在 Vue3 中实现 PDF 预览,推荐使用 `pdfjs-dist`(PDF.js 的官方分发包)结合 Vue 响应式 API。以下是完整实现方案:
#### 1. 安装依赖
```bash
npm install pdfjs-dist
```
#### 2. 组件实现 (`PdfPreview.vue`)
```vue
<template>
<div class="pdf-container">
<!-- 控制栏 -->
<div class="controls">
<button @click="prevPage" :disabled="pageNumber <= 1">上一页</button>
<span>第 {{ pageNumber }} 页 / 共 {{ numPages }} 页</span>
<button @click="nextPage" :disabled="pageNumber >= numPages">下一页</button>
<input
type="number"
v-model.number="inputPage"
min="1" :max="numPages"
@change="goToPage"
>
<button @click="rotate(-90)">左旋</button>
<button @click="rotate(90)">右旋</button>
<span>缩放: {{ scale }}%</span>
<button @click="zoom(0.1)">+</button>
<button @click="zoom(-0.1)">-</button>
</div>
<!-- 画布容器 -->
<div class="canvas-wrapper">
<canvas ref="canvasRef" class="pdf-canvas"></canvas>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
import * as pdfjsLib from 'pdfjs-dist/build/pdf';
import 'pdfjs-dist/build/pdf.worker.entry';
// 初始化 PDF.js
pdfjsLib.GlobalWorkerOptions.workerSrc = window.pdfjsWorker;
// 组件参数
const props = defineProps({
pdfUrl: {
type: String,
required: true
}
});
// 响应式状态
const canvasRef = ref(null);
const pageNumber = ref(1);
const numPages = ref(0);
const scale = ref(1.0);
const rotation = ref(0);
const inputPage = ref(1);
let pdfDoc = null;
// 加载PDF文档
const loadPdf = async () => {
try {
const loadingTask = pdfjsLib.getDocument(props.pdfUrl);
pdfDoc = await loadingTask.promise;
numPages.value = pdfDoc.numPages;
renderPage();
} catch (err) {
console.error('PDF加载失败:', err);
}
};
// 渲染当前页
const renderPage = async () => {
if (!pdfDoc || pageNumber.value < 1 || pageNumber.value > numPages.value) return;
const page = await pdfDoc.getPage(pageNumber.value);
const viewport = page.getViewport({
scale: scale.value,
rotation: rotation.value
});
const canvas = canvasRef.value;
const context = canvas.getContext('2d');
// 设置画布尺寸
canvas.height = viewport.height;
canvas.width = viewport.width;
// 渲染PDF页面
const renderContext = {
canvasContext: context,
viewport: viewport
};
await page.render(renderContext).promise;
};
// 页面导航
const prevPage = () => {
if (pageNumber.value > 1) {
pageNumber.value--;
inputPage.value = pageNumber.value;
}
};
const nextPage = () => {
if (pageNumber.value < numPages.value) {
pageNumber.value++;
inputPage.value = pageNumber.value;
}
};
const goToPage = () => {
const page = Math.max(1, Math.min(inputPage.value, numPages.value));
pageNumber.value = page;
};
// 旋转控制
const rotate = (angle) => {
rotation.value = (rotation.value + angle) % 360;
};
// 缩放控制
const zoom = (delta) => {
scale.value = Math.max(0.5, Math.min(scale.value + delta, 2.0));
};
// 监听状态变化
watch([pageNumber, scale, rotation], renderPage);
watch(() => props.pdfUrl, loadPdf);
// 生命周期钩子
onMounted(loadPdf);
onBeforeUnmount(() => {
if (pdfDoc) {
pdfDoc.destroy();
pdfDoc = null;
}
});
</script>
<style scoped>
.pdf-container {
max-width: 100%;
overflow: auto;
}
.controls {
margin-bottom: 15px;
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
}
.canvas-wrapper {
border: 1px solid #eee;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.pdf-canvas {
display: block;
margin: 0 auto;
}
</style>
```
#### 3. 使用示例 (`App.vue`)
```vue
<template>
<div>
<h1>PDF预览示例</h1>
<PdfPreview pdfUrl="/sample.pdf" />
</div>
</template>
<script setup>
import PdfPreview from './components/PdfPreview.vue';
</script>
```
### 功能说明
1. **核心实现**:
- 使用 PDF.js 的 `getDocument()` 加载 PDF
- 通过 Canvas API 渲染 PDF 页面
- 利用 Vue3 响应式 API 管理状态
2. **支持功能**:
- 分页导航(上一页/下一页/跳转)
- 页面旋转(左旋/右旋)
- 缩放控制(+/-按钮)
- 自适应画布尺寸
- 错误处理
3. **注意事项**:
- 确保 PDF 文件路径正确(支持 URL 或 base64)
- 跨域 PDF 文件需要服务端配置 CORS
- 大文件建议使用 CDN 加速加载
- 生产环境需配置 PDF.js worker
### 替代方案
如需更高级功能,可考虑以下库:
1. **Vue PDF Embed**:专为 Vue3 设计的轻量级组件
```bash
npm install vue-pdf-embed
```
2. **PDF.js Viewer**:官方完整查看器(需自定义集成)
> PDF.js 是 Mozilla 开源的 PDF 渲染库,支持现代浏览器并遵循 PDF 标准[^1]。
阅读全文
相关推荐


















