vue-pdf在vue框架中的使用

news2024/12/22 19:45:59

在components目录下新建PdfViewer/index.vue

vue-pdf版本为4.3.0

<template>
    <div :id="containerId" v-if="hasProps" class="container">
        <div class="right-btn">
            <div class="pageNum">
                <input v-model.number="currentPage" type="number" class="inputNumber" @input="inputEvent()"> / {{pageCount}}
            </div>
            <div @click="changePdfPage('first')" class="turn">首页</div>
            <div @click="changePdfPage('pre')" class="turn-btn" :style="currentPage===1?'cursor: not-allowed;':''">上一页</div>
            <div @click="changePdfPage('next')" class="turn-btn" :style="currentPage===pageCount?'cursor: not-allowed;':''">下一页</div>
            <div @click="changePdfPage('last')" class="turn">尾页</div>
            <div @click="scaleUp()" class="turn-btn">放大</div>
            <div @click="scaleDown()" class="turn-btn">缩小</div>
            <div @click="rotate()" class="turn-btn">旋转</div>
            <div @click="downPDF()" class="turn" v-if="isShowDownloadBtn">下载</div>
        </div>

        <div class="pdfArea">
            <pdf :src="src" :ref="pdfRef" :page="currentPage" @num-pages="pageCount=$event" @progress="loadedRatio = $event" @page-loaded="currentPage=$event" @loaded="loadPdfHandler" @link-clicked="currentPage = $event" style="display: inline-block;width:100%" />
        </div>
    </div>
</template>

<script>
import pdf from 'vue-pdf'

export default {
    name: "pdfViewer",
    props: {
        // src pdf资源路径
        src: {
            type: String,
            default: () => {
                return null;
            },
        },
        // 该pdf-viewer组件唯一id
        containerId: {
            type: String,
            default: () => {
                return null;
            },
        },
        // 该pdf-viewer组件唯一ref
        pdfRef: {
            type: String,
            default: () => {
                return null;
            },
        },
        // 是否展示下载按钮
        isShowDownloadBtn: {
            type: Boolean,
            default: () => {
                return false;
            }
        },
    },
    components: {
        pdf
    },
    computed: {
        hasProps() {
            return this.src && this.containerId && this.pdfRef;
        }
    },
    created() { },
    mounted() {
        this.$nextTick(() => {
            this.prohibit();
        })
    },
    data() {
        return {
            scale: 100,  //  开始的时候默认和容器一样大即宽高都是100%
            rotation: 0, // 旋转角度
            currentPage: 0, // 当前页数
            pageCount: 0, // 总页数
        }
    },
    methods: {
        rotate() {
            this.rotation += 90;
            this.$refs[this.pdfRef].$el.style.transform = `rotate(${this.rotation}deg)`;
            console.log(`当前旋转角度: ${this.rotation}°`);
        },
        // 页面回到顶部
        toTop() {
            document.getElementById(this.containerId).scrollTop = 0
        },
        // 输入页码时校验
        inputEvent() {
            if (this.currentPage > this.pageCount) {
                // 1. 大于max
                this.currentPage = this.pageCount
            } else if (this.currentPage < 1) {
                // 2. 小于min
                this.currentPage = 1
            }
        },
        // 切换页数
        changePdfPage(val) {
            if (val === 'pre' && this.currentPage > 1) {
                // 切换后页面回到顶部
                this.currentPage--
                this.toTop()
            } else if (val === 'next' && this.currentPage < this.pageCount) {
                this.currentPage++
                this.toTop()
            } else if (val === 'first') {
                this.currentPage = 1
                this.toTop()
            } else if (val === 'last' && this.currentPage < this.pageCount) {
                this.currentPage = this.pageCount
                this.toTop()
            }
            this.$refs[this.pdfRef].$el.style.transform = `rotate(0deg)`;
            this.rotation = 0;
        },

        // pdf加载时
        loadPdfHandler(e) {
            // 加载的时候先加载第一页
            // console.log(e);
            this.currentPage = 1
        },

        // 禁用鼠标右击、F12 来禁止打印和打开调试工具
        prohibit() {
            let node = document.querySelector(`#${this.containerId}`);
            node.oncontextmenu = function () {
                return false
            }
            node.onkeydown = function (e) {
                console.log("禁用", e);
                if (e.ctrlKey && (e.keyCode === 65 || e.keyCode === 67 || e.keyCode === 73 || e.keyCode === 74 || e.keyCode === 80 || e.keyCode === 83 || e.keyCode === 85 || e.keyCode === 86 || e.keyCode === 117)) {
                    return false
                }
                if (e.keyCode === 18 || e.keyCode === 123) {
                    return false
                }
            }
        },
        //放大
        scaleUp() {
            if (this.scale == 300) {
                return;
            }

            this.scale += 5;
            this.$refs[this.pdfRef].$el.style.width = parseInt(this.scale) + "%";
            this.$refs[this.pdfRef].$el.style.height = parseInt(this.scale) + "%";
            console.log(`当前缩放倍数: ${this.scale}%`);
        },
        //缩小
        scaleDown() {
            if (this.scale == 30) {
                return;
            }
            this.scale += -5;
            this.$refs[this.pdfRef].$el.style.width = parseInt(this.scale) + "%";
            this.$refs[this.pdfRef].$el.style.height = parseInt(this.scale) + "%";
            console.log(`当前缩放倍数: ${this.scale}%`);
        },
        // 下载
        downPDF() { // 下载 pdf
            var url = this.src
            var tempLink = document.createElement("a");
            tempLink.style.display = "none";
            tempLink.href = url;
            tempLink.setAttribute("download", 'XXX.pdf');
            if (typeof tempLink.download === "undefined") {
                tempLink.setAttribute("target", "_blank");
            }
            document.body.appendChild(tempLink);
            tempLink.click();
            document.body.removeChild(tempLink);
        },
    }
}
</script>

<style lang="scss" scoped>
#container {
    overflow: auto;
    height: 800px;
    font-family: PingFang SC;
    width: 100%;
    display: flex;
    /* justify-content: center; */
    position: relative;
}

.container {
    position: relative;
}

/* 右侧功能按钮区 */
.right-btn {
    // position: fixed;
    position: absolute;
    right: 10%;
    // bottom: 15%;
    top: 5%;
    width: 120px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    z-index: 99;
    user-select: none;
}

.pdfArea {
    width: 80%;
}

/* ------------------- 输入页码 ------------------- */
.pageNum {
    margin: 10px 0;
    font-size: 18px;
}
/*在谷歌下移除input[number]的上下箭头*/
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    -webkit-appearance: none !important;
    margin: 0;
}

.inputNumber {
    border-radius: 8px;
    border: 1px solid #999999;
    height: 35px;
    font-size: 18px;
    width: 60px;
    text-align: center;
}
.inputNumber:focus {
    border: 1px solid #00aeff;
    background-color: rgba(18, 163, 230, 0.096);
    outline: none;
    transition: 0.2s;
}

/* ------------------- 切换页码 ------------------- */
.turn {
    background-color: #888888;
    opacity: 0.7;
    color: #ffffff;
    height: 70px;
    width: 70px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 5px 0;
}

.turn-btn {
    background-color: #000000;
    opacity: 0.6;
    color: #ffffff;
    height: 70px;
    width: 70px;
    border-radius: 50%;
    margin: 5px 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.turn-btn:hover,
.turn:hover {
    transition: 0.3s;
    opacity: 0.5;
    cursor: pointer;
}

/* ------------------- 进度条 ------------------- */
.progress {
    position: absolute;
    right: 50%;
    top: 50%;
    text-align: center;
}
.progress > span {
    color: #199edb;
    font-size: 14px;
}
</style>

main.js中引用,全局注册

import PdfViewer from "@/components/PdfViewer"
Vue.component('PdfViewer', PdfViewer)

在项目中使用

<el-dialog>
    <PdfViewer :src="pdf地址" containerId="id,自定义" pdfRef="ref,自定义" :isShowDownloadBtn="布尔值,是否开启下载功能"></PdfViewer>
</el-dialog>

使用效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1221876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云端援手:智能枢纽应对数字资产挑战 ——华为云11.11应用集成管理与创新专区优惠限时购

现新客3.96元起&#xff0c;下单有机会抽HUAWEI P60 Art 福利仅限双十一 机会唾手可得&#xff0c;立即行动&#xff01; 「有效管理保护应用与数据的同时实现高效互通」——华为云全力满足企业需求&#xff0c;推出全套「应用集成管理与创新」智能解决方案&#xff1a;华为云…

系列四、GC垃圾回收【四大垃圾算法-引用计数法】

一、概述 Java中&#xff0c;引用和对象是有关联的&#xff0c;如果要操作对象则必须要用引用进行。因此判断一个对象是否可以被回收&#xff0c;很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。简单来讲就是给对象中添加一个引用计数器&#xff0c;每当一…

DataFrame.empty 与 DataFrame is None 的区别是?

请注意&#xff0c;empty 与 None 是不同的概念&#xff0c;这个要注意。不信我们试一下&#xff1a; import pandas as pddf pd.DataFrame()df ! df ! Nonedf.empty df is not None # 已经被赋值&#xff0c;为空但不为Nonea is None参考回答&#xff1a; DataFrame.empty…

【观察】华为:数智世界“一触即达”,应对数智化转型“千变万化”

毫无疑问&#xff0c;数智化既是这个时代前进所趋&#xff0c;也是国家战略所指&#xff0c;更是所有企业未来发展进程中达成的高度共识。 但也要看到&#xff0c;由于大量新兴技术的出现&#xff0c;技术热点不停的轮转&#xff0c;加上市场环境的快速变化&#xff0c;让数智化…

SpringBoot 2.x 实战仿B站高性能后端项目

SpringBoot 2.x 实战仿B站高性能后端项目 下栽の地止&#xff1a;请看文章末尾 通常SpringBoot新建项目&#xff0c;默认是集成了Maven&#xff0c;然后所有内容都在一个主模块中。 如果项目架构稍微复杂一点&#xff0c;就需要用到Maven多模块。 本文简单概述一下&#xff0c…

23111709[含文档+PPT+源码等]计算机毕业设计基于Spring Boot智能无人仓库管理-进销存储

文章目录 **软件开发环境及开发工具&#xff1a;****功能介绍&#xff1a;****论文截图&#xff1a;****数据库&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及…

最新AI创作系统ChatGPT系统运营源码+支持GPT-4多模态模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

iPhone 拨打分机号码

iPhone 拨打分机号码 假设现在一个电话号码12345678-9999&#xff0c;如何用iPhone拨打这个电话&#xff1f; 错误拨号方式 在拨号页面输出12345678拨打电话&#xff0c;会得到语言提示”请直播分机号码“。 在拨号页面输出123456789999拨打电话&#xff0c;会得到语音提示…

【打卡】牛客网:BM55 没有重复项数字的全排列

自己写的&#xff1a; 虽然题目要求了排序&#xff0c;但是我没排序也可以通过。 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param num int整型vector * return int整型vector<vec…

CSS特效013:背景色彩不停流动效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…

注解方式优雅的实现 Redisson 分布式锁

1前言 日常开发中&#xff0c;难免遇到一些并发的场景&#xff0c;为了保证接口执行的一致性&#xff0c;通常采用加锁的方式&#xff0c;因为服务是分布式部署模式&#xff0c;本地锁Reentrantlock和Synchnorized这些就先放到一边了&#xff0c;Redis的setnx锁存在无法抱保证…

和鲸科技创始人范向伟受邀出席“凌云出海,来中东吧”2023华为云上海路演活动

11月9日&#xff0c;华为云“凌云出海&#xff0c;来中东吧”系列路演活动第二场在上海正式开启。聚焦“创业全球化”&#xff0c;本次活动由华为云携手阿布扎比投资办公室&#xff08;ADIO&#xff09;举办&#xff0c;旨在与渴望出海发展的优秀创业者们共探出海中东新商机。 …

各品牌PLC元件在modbus内区域

1台达&#xff1a; 输出在0区&#xff0c; 040961是在 0区 0xA000~0xA0FF 【Y0~Y377】 输入在1区&#xff0c;124577是在 1区 0x6000~0x60FF 【X0~X377】 M寄存器0区&#xff0c;0000001是 0区&#xff0c;0x000~0x1FFF 【M0~M8191】 D寄存器4区&#xff0c;400000…

【完美世界】石昊身上宝术至尊骨、上苍之手和轮回宝术哪个最强

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 完美世界动画中&#xff0c;石昊通过举起天人族的镇教之宝飞仙石&#xff0c;终于补全了第一块至尊骨的天赋宝术-上苍之手。然而&#xff0c;这只是开始&#xff0c;上苍之手的终极奥义还需要他慢慢领悟。 在…

Pandas+Matplotlib 数据分析

利用可视化探索图表 一、数据可视化与探索图 数据可视化是指用图形或表格的方式来呈现数据。图表能够清楚地呈现数据性质&#xff0c; 以及数据间或属性间的关系&#xff0c;可以轻易地让人看图释义。用户通过探索图&#xff08;Exploratory Graph&#xff09;可以了解数据的…

在通用jar包中引入其他spring boot starter,并在通用jar包中直接配置这些starter的yml相关属性

场景 我在通用jar包中引入 spring-boot-starter-actuator 这样希望引用通用jar的所有服务都可以直接使用 actuator 中的功能&#xff0c; 问题在于&#xff0c;正常情况下&#xff0c;actuator的配置都写在每个项目的yml文件中&#xff0c;这就意味着&#xff0c;虽然每个项目…

Java 之拼图小游戏

声明 此项目为java基础的阶段项目,此项目涉及了基础语法,面向对象等知识,具体像语法基础如判断,循环,数组,字符串,集合等…; 面向对象如封装,继承,多态,抽象类,接口,内部类等等…都有涉及。此项目涉及的内容比较多,作为初学者可以很好的将前面的知识串起来。此项目拿来练手以及…

基于Pytorch的从零开始的目标检测

引言 目标检测是计算机视觉中一个非常流行的任务&#xff0c;在这个任务中&#xff0c;给定一个图像&#xff0c;你预测图像中物体的包围盒(通常是矩形的) &#xff0c;并且识别物体的类型。在这个图像中可能有多个对象&#xff0c;而且现在有各种先进的技术和框架来解决这个问…

物联网AI MicroPython学习之语法UART通用异步通信

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; UART 介绍 模块功能: UART通过串行异步收发通信 接口说明 UART - 构建UART对象 函数原型&#xff1a;UART(id, baudrate&#xff0c;bits, parity&#xff0c;stop, tx, rx)参数说明&#xff1a; 参数类…

Ubuntu22.04 Apache2安装SSL证书 https

一、免费证书申请 https://help.aliyun.com/zh/ssl-certificate/user-guide/overview-of-free-certificates 得到 三、配置 执行以下命令&#xff0c;打开default-ssl.conf文件。 vim /etc/apache2/sites-available/default-ssl.conf 在default-ssl.conf配置文件中&#xff…