Vue3+Vite项目,实现自定义pdf查看并实现禁用下载复制
npm install vue3-pdfjs
npm install vue-pdf-embed
测试版本: vue3-pdfjs @1.1.4; vue3-pdfjs @0.1.6;
配置main.js
import VuePdf from 'vue3-pdfjs'
app.use(router).use(ElementPlus).use(VuePdf);
在components文件夹新建组件,命名为” pdfPreview.vue”
<template>
<div class="pdf-preview">
<vue-pdf-embed :source="props.pdfUrl" :style="scale" class="vue-pdf-embed" :page="state.pageNum" />
</div>
<div class="page-tool">
<div class="page-tool-item" @click="lastPage">上一页</div>
<div class="page-tool-item" @click="nextPage">下一页</div>
<div class="page-tool-item noPointer">{{state.pageNum}} / {{state.numPages}}</div>
<div class="page-tool-item" @click="pageZoomOut">放大</div>
<div class="page-tool-item bite noPointer">{{biteNum}}%</div>
<div class="page-tool-item" @click="pageZoomIn">缩小</div>
</div>
</template>
<script setup lang="ts">
import { reactive, onMounted, computed,ref,watch } from "vue";
import VuePdfEmbed from "vue-pdf-embed";
import { createLoadingTask } from "vue3-pdfjs/esm";
import { ElMessage } from "element-plus";
const props = defineProps({
pdfUrl: {
type: String,
required: true
}
})
let getUrl = ref('')
watch(() => props.pdfUrl,
(newValue, oldValue) => {
setTimeout(function () {
getUrl.value = newValue;
console.log('getUrl',getUrl.value)
if (getUrl.value) {
onloadPdf()
}else{
console.log('warning');
}
}, 0);
},
{ deep: true, immediate: true }
)
const state = reactive({
source: props.pdfUrl, // 预览pdf文件地址
pageNum: 1, // 当前页面
scale: 1, // 缩放比例
paddingTop:0,
paddingLeft:0,
numPages: 15, // 总页数
});
function onloadPdf(){
const loadingTask = createLoadingTask(getUrl.value);
loadingTask.promise.then((pdf:{numPages: number}) => {
state.numPages = pdf.numPages;
});
}
onMounted(() => {
// console.log('getUrl',props.pdfUrl);
});
const scale = computed(() => `
transform:scale(${state.scale});
padding: ${state.paddingTop}px ${state.paddingLeft}px ${state.paddingTop}px ${state.paddingLeft}px;
`)
function lastPage() {
if (state.pageNum > 1) {
setTimeout(function() {
state.pageNum -= 1;
}, 200);
}
}
function nextPage() {
if (state.pageNum < state.numPages) {
setTimeout(function() {
state.pageNum += 1;
}, 200);
}
}
let biteNum = ref(100);
function pageZoomOut() {
if (state.scale < 1.2) {
state.scale += 0.1;
state.paddingTop += 28;
state.paddingLeft += 40;
}else{
ElMessage({
message: '不能再放大了',
type: "warning",
duration:800
});
}
biteNum.value = (state.scale *100)^0
}
function pageZoomIn() {
if (state.scale > 0.8) {
state.scale -= 0.1;
state.paddingTop -= 28;
state.paddingLeft -= 40;
}else{
ElMessage({
message: '不能再缩小了',
type: "warning",
duration:800
});
}
biteNum.value = (state.scale *100)^0
}
</script>
<style lang="css" scoped>
.pdf-preview {
position: relative;
height: 90vh;
overflow-y: auto;
box-sizing: border-box;
display: flex;
}
.vue-pdf-embed {
width: 98%;
}
.vue-pdf-embed>div{
height: 90vh;
}
.vue-pdf-embed canvas{
height: 90vh !important;
}
.page-tool {
font-size: 14px;
position: absolute;
bottom: 35px;
padding-left: 15px;
padding-right: 15px;
display: flex;
align-items: center;
background: rgb(66, 66, 66);
color: white;
border-radius: 19px;
z-index: 100;
cursor: pointer;
margin-left: 50%;
transform: translateX(-50%);
}
.page-tool-item {
padding: 8px 15px;
padding-left: 10px;
cursor: pointer;
}
.bite{
width: fit-content;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 8px !important;
}
.noPointer{
cursor: default;
}
.pdf-preview::-webkit-scrollbar{
width: 10px;
height: 10px;
}
.pdf-preview::-webkit-scrollbar-thumb{
background-color: rgba(255, 255, 219, 0.1) ;
border: #666 solid 1px;
border-radius: 4px;
}
</style>
父组件引用,传入pdf地址
<div class="pdfShlle" v-if="(scanPdfStatus === true)" @contextmenu.prevent="openMenu($event)">
<ul class="headerNav">
<li>{{ pdfName }}</li>
<el-button type="primary" style="position: absolute;right: 40px;top: 14px; "
@click="backList()">返回</el-button>
</ul>
<div class="mode">
<div class="PdfBox">
<div>
<PDFView :pdfUrl="pdfUrl"></PDFView>
</div>
</div>
</div>
</div>
<script setup>
import { getCurrentInstance, ref } from "vue";
import { useRoute } from "vue-router";
import PDFView from "../pdfPreview.vue"
let pdfName = ref('');
let pdfUrl = ref(null);
</script>
<style scoped>
/* 查看pdf */
.pdfShlle {
width: 100%;
height: 100vh;
position: fixed;
z-index: 9;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #303030;
padding: 0 40px;
box-sizing: border-box;
user-select: none;
}
.headerNav {
width: 100%;
height: 8vh;
line-height: 8vh;
background-color: #333;
padding-left: 20px;
box-sizing: border-box;
font-size: 18px;
color: #fff;
letter-spacing: 2px;
}
.mode {
width: 85%;
margin: auto;
height: 86vh;
position: relative;
}
.PdfBox {
width: 100%;
height: 86vh;
}
.PdfBox>div {
position: relative;
height: 86vh;
width: 100%
}
</style>