vue-pdf插件(在同一页面切换显示时,渲染会有问题)
- npm install --save vue-pdf
- 封装组件
<template>
<div>
<div>
<el-button @click="zoomIn">+</el-button>
<el-button @click="zoomOut">-</el-button>
</div>
<pdf :src="src" v-for="i in numPages" :key="i" :page="i" style="width: 100%;"></pdf>
</div>
</template>
<script>
import pdf from 'vue-pdf'
export default{
name:'pdfItem',
props:{
pdfSrc:{
type:String
}
},
components:{
pdf
},
data(){
return {
src:'',
numPages:1,
scale:100
}
},
created(){
this.getPdfUrl()
},
methods:{
getPdfUrl() {
let _this = this
this.src = pdf.createLoadingTask(this.pdfSrc)
this.src.promise.then(pdf => {
_this.numPages = pdf.numPages
}).catch((err) => {
console.error('pdf加载失败',err)
})
},
zoomIn(){
this.scale += 5
this.$refs.pdf.map(item=>item.$el.style.width = parseInt(this.sacle) + '%')
},
zoomOut(){
if(this.scale === 100){
return
}
this.scale -= 5
this.$refs.pdf.map(item=>item.$el.style.width = parseInt(this.scale) + '%')
},
}
}
</script>
pdfjs-dist插件
- npm install pdfjs-dist
- 封装组件
<template>
<div class="pdf-container">
<div class="pdf-controller">
<el-button size="mini" class="pdf-plus" icon="el-icon-zoom-in" @click="plus_btn"></el-button>
<el-button size="mini" class="pdf-minus" icon="el-icon-zoom-out" @click="minus_btn"></el-button>
</div>
<el-scrollbar style="max-height: 600px;overflow-y: scroll;">
<canvas v-for="index in totalPage" :key="index" :id="`canvas-${index}`"></canvas>
</el-scrollbar>
</div>
</template>
<script>
import PDFJS from 'pdfjs-dist'
const workerSrc = require('pdfjs-dist/build/pdf.worker.min.js')
export default {
name: 'new-pdf-item',
props: ['pdfurl'],
data() {
return {
pdfDoc: null,
pageNum: 1,
pageRendering: false,
pageNumPending: null,
scale: 1,
page_num: 0,
maxscale: 50,
minscale: 1,
totalPage:0,
}
},
methods: {
renderPage(num) {
console.log('scale',this.scale)
let vm = this;
this.pageRendering = true;
this.pdfDoc.getPage(num).then(pdfPage => {
let viewport = pdfPage.getViewport(vm.scale);
let canvas = document.getElementById('the-canvas')
canvas.width = viewport.width;
canvas.height = viewport.height;
let ctx = canvas.getContext('2d')
let renderContext = {
canvasContext: ctx,
viewport: viewport
};
let renderTask = pdfPage.render(renderContext);
renderTask.promise.then(function() {
vm.pageRendering = false;
if(vm.pageNumPending !== null) {
vm.renderPage(vm.pageNumPending);
vm.pageNumPending = null;
}
});
});
vm.page_num = vm.pageNum;
},
addscale() {
if(this.scale >= this.maxscale) {
return
}
this.scale += 1;
this.queueRenderPage(this.pageNum)
},
minus() {
if(this.scale <= this.minscale) {
return
}
this.scale -= 1;
this.queueRenderPage(this.pageNum)
},
prev() {
let vm = this
if(vm.pageNum <= 1) {
return;
}
vm.pageNum--;
vm.queueRenderPage(vm.pageNum);
},
next() {
let vm = this;
if(vm.pageNum >= vm.totalPage) {
return;
}
vm.pageNum++;
vm.queueRenderPage(vm.pageNum);
},
queueRenderPage(num) {
if(this.pageRendering) {
this.pageNumPending = num;
} else {
this.renderPage(num);
}
},
loadPage(){
console.log('scale',this.scale)
let pdfDocument = this.pdfDoc
for (let i = 1; i <= pdfDocument.numPages; i++) {
pdfDocument.getPage(i).then(pdfPage => {
let viewport = pdfPage.getViewport(this.scale)
let canvas = document.getElementById(`canvas-${i}`)
canvas.width = viewport.width
canvas.height = viewport.height
let ctx = canvas.getContext('2d')
let renderTask = pdfPage.render({
canvasContext: ctx,
viewport: viewport
})
return renderTask.promise
})
}
},
plus_btn(){
if(this.scale >= this.maxscale) {
return
}
this.scale += 0.2;
this.loadPage()
},
minus_btn(){
if(this.scale <= this.minscale){
return;
}
this.scale -= 0.2;
this.loadPage()
},
},
computed: {
},
mounted() {
PDFJS.GlobalWorkerOptions.workerSrc = workerSrc
PDFJS.getDocument(this.pdfurl).promise.then(pdfDocument => {
this.pdfDoc = pdfDocument
this.totalPage = pdfDocument.numPages
this.loadPage()
}).catch(reason => console.error('PDF加载失败'))
}
}
</script>
<style lang="scss" scoped>
.canvasstyle{
width: 100%;
height:100%;
}
.cpdf{
color:#fff
}
.pdf-controller{
margin: 10px 0;
// text-align: center;
}
.pdf-plus,.pdf-minus{
font-size: 14px;
}
.pdf-page{
padding: 0 10px;
}
</style>