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

本文介绍了如何在Vue应用中使用vue-pdf组件实现PDF文件的分页浏览,包括全屏模式、页面切换、滚动事件和处理跨域问题的方法。
摘要由CSDN通过智能技术生成
<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在前端文件夹 正常。后端服务器的文件会一直报跨域报错,并且我后台已经设置了跨域还是报。

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue-pdf是一个用于在Vue应用程序中显示PDF文档的JavaScript库。它允许你轻松地将PDF文件嵌入到你的Vue组件中,并提供了一些有用的功能,如缩放、翻页、全屏模式等。 以下是如何在Vue应用程序中使用vue-pdf的步骤: 1. 首先,在你的Vue项目中安装vue-pdf。你可以使用npm命令来完成此操作: ``` npm install vue-pdf --save ``` 2. 在你的Vue组件中导入vue-pdf: ```javascript import pdf from 'vue-pdf' ``` 3. 在你的Vue组件中,将vue-pdf作为一个子组件来使用。你需要传递一个PDF文件的URL或一个包含PDF文件的二进制数据的Blob对象作为prop。 ```html <template> <div> <pdf :src="pdfUrl"></pdf> </div> </template> <script> import pdf from 'vue-pdf' export default { components: { pdf }, data () { return { pdfUrl: 'https://example.com/my-pdf-file.pdf' } } } </script> ``` 4. 现在,你可以在你的Vue应用程序中看到PDF文件了。你可以使用vue-pdf提供的一些功能来控制PDF显示,比如缩放、翻页、全屏模式等。 例如,你可以使用缩放功能来让用户放大或缩小PDF文件: ```html <template> <div> <pdf :src="pdfUrl" :scale="scale"></pdf> <button @click="zoomIn">放大</button> <button @click="zoomOut">缩小</button> </div> </template> <script> import pdf from 'vue-pdf' export default { components: { pdf }, data () { return { pdfUrl: 'https://example.com/my-pdf-file.pdf', scale: 1.0 } }, methods: { zoomIn () { this.scale += 0.1 }, zoomOut () { this.scale -= 0.1 } } } </script> ``` 这样,你就可以使用vue-pdf在你的Vue应用程序中显示PDF文件了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值