Vue 使用vue-pdf 显示pdf文件 切换页面 缩放 全屏 自动播放等

2023-09-18 14:06:04
<template>
    <div id="container">
        <!-- 上一页、下一页-->
        <div class="right-btn">
            <div @click="toFullOrExit" class="turn-btn"><span>{{ isFull == 1 ? "取消全屏" : "全屏" }}</span></div>
            <div @click="changePdfPage('first')" class="turn">
                首页
            </div>
                        <!-- 输入页码 -->
                        <div class="pageNum">
                <input v-model.number="currentPage" type="number" class="inputNumber" @input="inputEvent()"> / {{ pageCount
                }}
            </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-btn">
                尾页
            </div>
            <div @click="scaleD" class="turn-btn">
                放大
            </div>
            <div><input type="number" class="inputNumber" @input="ScaleDX" v-model="scale">%</div>
            <div @click="scaleX" class="turn-btn">
                缩小
            </div>
            <div @click="AutoPdfPage()" :class="AutoPage == true ? 'turn-autobtn' : 'turn-btn'">
                自动播放
            </div>
            <div><input type="number" class="inputNumber" v-model="AutoTime">秒</div>
        </div>
        <div class="pdfArea">
            <pdf :src="src" ref="pdf" v-show="loadedRatio === 1" :page="currentPage" @num-pages="pageCount = $event"
                @progress="loadedRatio = $event" @page-loaded="currentPage = $event" @loaded="loadPdfHandler"
                @link-clicked="currentPage = $event" id="pdfID" style="margin: auto;"></pdf>
        </div>
        <!-- 加载未完成时,展示进度条组件并计算进度 -->
        <div class="progress" v-show="loadedRatio !== 1">
            <el-progress type="circle" :width="70" color="#53a7ff"
                :percentage="Math.floor(loadedRatio * 100)"></el-progress>
            <br>
            <!-- 加载提示语 -->
            <span>{{ remindShow }}</span>
        </div>
    </div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
    components: {
        pdf
    },
    computed: {
    },
    created() {
        this.prohibit()
    },
    destroyed() {
        // 在页面销毁时记得清空 setInterval
        clearInterval(this.intervalID)
    },
    mounted() {
        // 更改 loading 文字
        this.intervalID = setInterval(() => {
            this.remindShow === this.remindText.refresh
                ? this.remindShow = this.remindText.loading
                : this.remindShow = this.remindText.refresh
        }, 4000)
        this.ID = this.$route.query.ID;
        this.getDocumentData();
        // // 监听滚动条事件
        // this.listenerFunction()
    },
    data() {
        return {
            // ----- loading -----
            remindText: {
                loading: '加载文件中,文件较大请耐心等待...',
                refresh: '若卡住不动,可刷新页面重新加载...'
            },
            remindShow: '加载文件中,文件较大请耐心等待...',
            intervalID: '',
            // ----- vuepdf -----
            // src静态路径: /static/xxx.pdf /static/1.pdf
            // src服务器路径: 'http://.../xxx.pdf'
            src: "",
            // 当前页数
            currentPage: 0,
            // 总页数
            pageCount: 0,
            // 加载进度
            loadedRatio: 0,
            //是否自动播放
            AutoPage: false,
            timer: null,
            ID: "",
            AutoTime: 5,
            scale: 100,
            isFull: 0,
        }
    },
    methods: {
        async getDocumentData() {
            if (this.ID == null || this.ID == "") {
                this.$message.error("当前页面异常!");
                return;
            }
            let res = await this.http.get('/api/Document/GetDocumentData', {
                id: this.ID
            })
            if (!res.Status && res.Code == -1) {
                this.$message.error(res.Message);
                return;
            }
            if (res.Data && res.Data.Res) {
                this.fileData = res.Data.Res;
                this.src = this.fileData.PreViewPath;
                // this.src = pdf.createLoadingTask(this.src)
                // console.log(this.src);
            }
        },
        // // 监听滚动条事件
        // listenerFunction(e) {
        //     document.getElementById('container').addEventListener('scroll', true)
        // },
        // 页面回到顶部
        toTop() {
            document.getElementById('container').scrollTop = 0
        },
        // 输入页码时校验
        inputEvent() {
            if (this.currentPage > this.pageCount) {
                // 1. 大于max
                this.currentPage = this.pageCount
            } else if (this.currentPage < 1) {
                // 2. 小于min
                this.currentPage = 1
            }
        },
        //放大
        scaleD() {
            this.scale += 5;
            this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
        },

        //缩小
        scaleX() {
            if (this.scale == 0) {
                return;
            }
            this.scale += -5;
            this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
        },
        ScaleDX() {
            this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
        },
        // 切换页数
        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()
            }
        },
        AutoPdfPage() {
            var AutoTime = this.AutoTime * 1000
            this.AutoPage = this.AutoPage == true ? false : true;
            if (this.AutoPage == true) {
                this.$message({
                    type: "success",
                    message: "自动播放启动 " + this.AutoTime + "S自动翻页",
                });
                this.timer = setInterval(() => {
                    console.log(this.currentPage);
                    if (this.currentPage == this.pageCount) {
                        this.currentPage = 1;
                    }
                    else {
                        this.currentPage++;
                    }
                }, AutoTime)
            }
            else {
                this.$message({
                    type: "success",
                    message: "自动播放停止",
                });
                clearInterval(this.timer);
            }


        },
        // pdf加载时
        loadPdfHandler(e) {
            // 加载的时候先加载第一页
            this.currentPage = 1
        },
        //全屏
        requestFullScreen() {
            let de = document.documentElement
            if (de.requestFullscreen) {
                de.requestFullscreen()
            } else if (de.mozRequestFullScreen) {
                de.mozRequestFullScreen()
            } else if (de.webkitRequestFullScreen) {
                de.webkitRequestFullScreen()
            }
        },
        //退出全屏
        exitFullscreen() {
            let de = document
            if (de.exitFullscreen) {
                de.exitFullscreen()
            } else if (de.mozCancelFullScreen) {
                de.mozCancelFullScreen()
            } else if (de.webkitCancelFullScreen) {
                de.webkitCancelFullScreen()
            }
        },
        //全屏切换
        toFullOrExit() {
            this.isFull = !this.isFull
            if (this.isFull) {
                this.requestFullScreen()
            } else {
                this.exitFullscreen()
            }
        },
        // // 禁用鼠标右击、F12 来禁止打印和打开调试工具
        // prohibit() {
        //     // console.log(document)
        //     document.oncontextmenu = function () {
        //         return false
        //     }
        //     document.onkeydown = function (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
        //         }
        //     }
        // }
    }
}
</script>
  
<style scoped>
#container {
    overflow: auto;
    height: 100%;
    font-family: PingFang SC;
    width: 100%;
    display: flex;
    /* justify-content: center; */
    position: relative;
}

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

.pdfArea {
    width: 100%;
}

/* ------------------- 输入页码 ------------------- */
.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;
}

在firefox下移除input[number]的上下箭头 input[type='number'] {
    -moz-appearance: textfield;
}

.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: #24aceb;
    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: #24aceb;
    opacity: 0.6;
    color: #ffffff;
    height: 70px;
    width: 70px;
    border-radius: 50%;
    margin: 5px 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.turn-autobtn {
    background-color: #0467fa;
    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>
  
  

中途发现如果PDF在前端文件夹 正常。后端服务器的文件会一直报跨域报错,并且我后台已经设置了跨域还是报。

最终解决是在前端代理里加入

更多推荐

线性搜索简介

概念:线性搜索(LinearSearch)是一种简单直观的搜索算法,用于在一个未排序或已排序的数组中查找目标元素。它从数组的第一个元素开始逐个比较,直到找到匹配的元素或搜索完整个数组。线性搜索解决的问题是在一个集合中查找特定元素的位置或判断元素是否存在。算法特点:简单直观:线性搜索是一种最基本的搜索算法,易于理解和实现

成都瀚网科技:抖音提供差异化​​亮点!

在抖音平台上,精选联盟是一个专门为优质品牌提供展示和推广机会的合作项目。对于斗店主来说,如何成功对接精选联盟并实现上市是一个重要目标。在这篇文章中,我们将分享一些豆点与精选联盟对接的方法,并提供上币指南。1、提升店铺品质精选联盟注重优质品牌的展示。因此,提升门店品质是成功对接精选联盟的关键。确保店铺拥有良好的信誉、优质

手机悬浮提词器怎么设置?分享三个简单的操作方法

在现代社会中,手机已成为人们生活中必不可少的一部分。随着科技的不断发展,手机的功能也越来越强大,如今手机悬浮提词器已成为许多人工作或学习时必备的工具。下面将分享三个简单的操作方法,帮助大家更好地设置手机悬浮提词器。打开悬浮窗口首先,我们可以在手机中打开书单视频王应用,进入首页后可以看到提词器功能,如果在面对手机发言时不

大模型RLHF算法更新换代,DeepMind提出自训练离线强化学习框架ReST

文章链接:https://arxiv.org/abs/2308.08998大模型(LLMs)爆火的背后,离不开多种不同基础算法技术的支撑,例如基础语言架构Transformer、自回归语言建模、提示学习和指示学习等等。这些技术造就了像GPT-3、PaLM等基座生成模型,在这些基座模型之上,研究人员通过引入人类反馈的强化

【大数据开发技术】实验05-HDFS目录与文件的创建删除与查询操作

文章目录一、实验目标二、实验要求三、实验内容四、实验步骤一、实验目标熟练掌握hadoop操作指令及HDFS命令行接口掌握HDFS目录与文件的创建方法和文件写入到HDFS文件的方法掌握HDFS目录与文件的删除方法掌握查询文件状态信息和目录下所有文件的元数据信息的方法二、实验要求给出主要实验步骤成功的效果截图。要求分别在本

【数字人】1、SadTalker | 使用语音驱动单张图片合成视频(CVPR2023)

SadTalker:使用一张图片和一段语音来生成口型和头、面部视频论文:SadTalker:LearningRealistic3DMotionCoefficientsforStylizedAudio-DrivenSingleImageTalkingFaceAnimation代码:https://github.com/W

计算机视觉与深度学习-卷积神经网络-卷积&图像去噪&边缘提取-卷积与边缘提取-[北邮鲁鹏]

目录标题参考学习链接什么是图像边缘?为什么研究边缘?有哪些边缘种类?表面法向不连续深度不连续表面颜色不连续光照不连续如何检测边缘?图像求导图像梯度图像梯度的方向图像梯度的模噪声的影响噪声影响带来的问题解决办法(先平滑处理)高斯核去噪高斯一阶偏导核高斯核vs高斯一阶偏导核边缘检测目标Canny边缘检测器高斯一阶偏导核卷积

如何从主机环境演变到云原生开发模式?

时代在发展,我们的知识,开发工具,以及相应的环境也随之进步,我们总是会趋向于向好的一面发展,期望我们自身能够更加优秀,更加高效,以及能够给周围的人带来更多的价值那么在我们平日开发过程中,你们的开发模式,以及开发环境是如何演变的呢?如下是我近一两年经历的变化,希望能给你们带来一些思考和收获混沌之初还是主机环境起初在接触g

Redis淘汰策略-架构案例2020(三十六)

上篇案例回顾:解释器,管道过滤,隐式调用优缺点?解释器则是独立的语法规则,可以通过解释器来解析,可扩展性很高,灵活性强。管道过滤则是侧重于数据的输入和输出,上一个模块的数据输出是下一个模块的输入,连接件事管道,过滤则是构件。隐式调用则强调触发和异步,多个构件会注册到一个模块里,当模块改变的时候,构件都会接收到消息从而跟

以酒为媒、以酒载道,五粮液携手首届“金熊猫奖”,讲好中国白酒故事

执笔|尼奥编辑|萧萧这是一次光影艺术与白酒酿造的和美之约,也是中国文化与世界多元文明的交融时刻,在影视与美酒的碰撞瞬间,共同擘画“美美与共,天下大同”的文明图景。9月19-20日,以“多彩文明·荣耀光影”为主题的首届“金熊猫奖”评选活动在成都举行。五粮液作为首届“金熊猫奖”全球战略合作伙伴亮相,深度融入金熊猫之夜、金熊

【C++】vector中的常见函数和使用

前言感觉vector在目前阶段很常用,就总结记录一些vector的用法方便自己忘记的时候查找因为是自用,所以我直接放代码了,只说明如何使用,以及一些小的注意点,对于函数具体实现过程,在这篇文章中,不做过多说明当然,我也给出了一些使用例子,供大家参考本文参考:C++vector操作代码#include<iostream>

热文推荐