往期回顾:vue3中使用 vue-pdf-embed 实现pdf文件预览、翻页、下载等功能
运行环境:
vue-pdf-embed@1.2.1
vue3-pdfjs@0.1.6
vue@3.3.11
vite@5.0.8
Windows 10
源代码:
html
结构内容:
<template>
<div id="vue-pdf-view" >
<div id="page-view" :style="{
position: 'absolute',
top: '50%',
left: '50%',
transform: `translate(-50%,-50%) scale(${scaleData})`,
width: '100%',
height: `${pageHeight}`,
}">
<!-- 单页展示 -->
<vue-pdf-embed :source="pdfState.url" :page="pdfState.pageNum" textLayer v-show="onlyPage" ref="vuePdfRef" />
<!-- 多页展示 -->
<vue-pdf-embed :source="pdfState.url" v-for="page in pdfState.numPages" :page="page" :key="page" textLayer v-if="manyPage" />
</div>
</div>
<span>
<button v-show="manyPage" @click="changePageMode">多页</button>
<button v-show="onlyPage" @click="changePageMode">单页</button>
</span>
<br>
<button @click="pageUp">上一页</button>
<button @click="pageDown">下一页</button>
<br>
<button @click="zoomIn">放大</button>
<button @click="zoomOut">缩小</button>
</template>
js
功能实现:
<script setup>
import { onMounted, reactive, ref } from 'vue';
import { createLoadingTask } from 'vue3-pdfjs/esm';
import VuePdfEmbed from "vue-pdf-embed";
// 文件路径
import pdfUrl from './compressed.tracemonkey-pldi-09.pdf';
const pdfState = reactive({
url: pdfUrl,
// 当前页
pageNum: 1,
// 总页数
numPages: 1,
})
onMounted(() => {
const loadingTask = createLoadingTask(pdfState.url);
loadingTask.promise.then((pdf) => {
// 获取页面总页数
pdfState.numPages = pdf.numPages;
});
});
// -- 缩放功能 --
const scaleData = ref(1.0);
const pageHeight = ref('100%');
// 放大
function zoomIn() {
scaleData.value += 0.1;
pageHeight.value = (parseInt(pageHeight.value) - 5.0) + '%';
}
// 缩小
function zoomOut() {
scaleData.value -= 0.1;
pageHeight.value = (parseInt(pageHeight.value) + 5.0) + '%';
}
// -- 页面 单页/多页 模式展示切换 --
const onlyPage = ref(true);
const manyPage = ref(false);
function changePageMode() {
onlyPage.value = !onlyPage.value;
manyPage.value = !manyPage.value;
}
</script>
注:此时页面可正常缩放且不闪烁,单/多 页转换时页面可正常显示。
效果演示(正常):
问题描述:
当 vue-pdf-embed
的 source
参数使用对象类型的写法时,页面出现闪烁且切换至单页模式后页面内容丢失。
对象类型的写法:
<vue-pdf-embed :source="{
url: pdfState.url,
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.9.359/cmaps/',
cMapPacked: true,
}" :page="pdfState.pageNum" textLayer v-show="onlyPage" ref="vuePdfRef" />
效果演示(异常):
尝试解决:
尝试注释 cMapUrl
和 cMapPacked
参数后问题依然存在。
在网上查找资料后发现以下写法,依然无效,这种写法获取到的pdf信息无法影响到 vue-pdf-embed
组件。
onMounted(() => {
// 此方法无效
const loadingTask = createLoadingTask(pdfState.url, {
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.9.359/cmaps/',
cMapPacked: true
})
loadingTask.promise.then((pdf) => {
// 获取页面总页数
pdfState.numPages = pdf.numPages;
});
})
解决方案:
定义变量时添加新的对象即可:
<script setup>
const pdfState = reactive({
pdfSource: {
url: pdfUrl,
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.9.359/cmaps/',
cMapPacked: true,
},
...
});
onMounted(() => {
const loadingTask = createLoadingTask(pdfState.pdfSource);
...
});
</script>
<template>
<vue-pdf-embed :source="pdfState.pdfSource" :page="pdfState.pageNum" textLayer ref="vuePdfRef" v-show="onlyPage"/>
<vue-pdf-embed :source="pdfState.pdfSource" v-for="page in pdfState.numPages" :page="page" :key="page" textLayer v-if="manyPage" />
</template>