vue移动端pdf在线预览,并实现手势缩放、移动
程序员文章站
2022-03-22 10:41:34
通常我们会遇到ios手机不能下载文件的问题,那是因为苹果手机的拦截机制,这时我们只能通过别的方法来解决问题,我这里的解决方法是直接实现在线预览pdf预览跟图片预览不同,pdf可能会有多张,而图片只有一张,使用图片预览的组件肯定是行不通的这里我使用的是一个vue-pdf的插件,这是一个使用起来容易上手的插件。首先我们需要在vue项目中引入它:npm install --save vue-pdf然后在展示pdf的页面引用import pdf from ‘vue-pdf’要想让pdf实现...
通常我们会遇到ios手机不能下载文件的问题,那是因为苹果手机的拦截机制,这时我们只能通过别的方法来解决问题,我这里的解决方法是直接实现在线预览
- pdf预览跟图片预览不同,pdf可能会有多张,而图片只有一张,使用图片预览的组件肯定是行不通的
- 这里我使用的是一个vue-pdf的插件,这是一个使用起来容易上手的插件。首先我们需要在vue项目中引入它:
npm install --save vue-pdf
然后在展示pdf的页面引用
import pdf from ‘vue-pdf’
- 要想让pdf实现手势缩放和移动,也需要导入插件,这里我使用的是AlloyFinger 超轻量级 Web 手势库,首先我们需要在vue项目引入它:
npm install alloyfinger
然后在main.js中导入
//Alloyfinger手势插件
import AlloyFinger from 'alloyfinger'
import AlloyFingerPlugin from 'alloyfinger/vue/alloy_finger_vue'
Vue.use(AlloyFingerPlugin,{
AlloyFinger
})
html代码
<template>
<div class="pdf-tab">
<div
class="btn-def btn-pre"
@click.stop="prePage">上一页
</div>
<div
class="btn-def btn-next"
@click.stop="nextPage">下一页
</div>
</div>
<div>{{pageNum}}/{{pageTotalNum}}</div>
<div class="any-scroll-view">
<div ref="body" :style="bodyStyle">
<pdf
id="pdfPreview"
ref="pdf"
:src="pdfUrl"
:page="pageNum"
:rotate="pageRotate"
@password="password"
@progress="loadedRatio = $event"
@page-loaded="pageLoaded($event)"
@num-pages="pageTotalNum=$event"
@error="pdfError($event)"
@link-clicked="page = $event">
</pdf>
</div>
</div>
</div>
</template>
js代码和style代码
alloyfinger.js、transform.js、to.js引入的这三个js里封装了手势缩放移动、旋转的方法,可以去GitHub将源码挡下来,将这三个js复制到自己的static文件下,然后引用即可。点此进入GitHub
<script>
import pdf from 'vue-pdf'
import AlloyFinger from "../../../static/js/alloyfinger.js";
import transform from "../../../static/js/transform.js";
import To from "../../../static/js/to.js";
export default {
name: 'mistakesVoucher',
props: {
// 减速度, 单位px/s²
acceleration: {
type: Number,
default: 3600
}
},
data() {
return {
id: '',
pdfUrl:'',// pdf文件地址
pageNum:1,
pageTotalNum:1,
pageRotate:0,
// 加载进度
loadedRatio:0,
curPageNum:0,
transitionDuration: 300,
goPath: '', //将要去的界面
};
},
beforeRouteEnter (to, from, next) { //监听从哪个页面过来
let path = from.fullPath;
next(vm => vm.setPath(path));
},
created(){
this.getParams()
},
computed: {
bodyStyle() {
return {
transitionDuration: `${this.transitionDuration}ms`,
transform: `translate(${this.scrollLeft}px, ${
this.scrollTop
}px)`
};
}
},
mounted() {
this.getData();
},
methods: {
setPath(path) {
this.goPath = path.split("/")[1];
},
//返回键
back() {
this.$router.push({
name: this.goPath,
params: {
id: this.id
}
})
},
getParams() {
// 取到路由带过来的参数
let routerParams = this.$route.params.id
// 将数据放在当前组件的数据内
this.id = routerParams
this.pdfUrl = pdf.createLoadingTask(this.$route.params.url)
},
getData() {
let that = this;
let element = document.getElementById("pdfPreview");
Transform(element);
var initScale = 1;
this.af = new AlloyFinger(element, {
rotate: function (evt) { //实现旋转
element.rotateZ += evt.angle;
},
multipointStart: function () {
initScale = element.scaleX;
},
pinch: function (evt) { //实现缩放
element.scaleX = element.scaleY = initScale * evt.zoom;
},
pressMove: function (evt) { //实现移动
element.translateX += evt.deltaX;
element.translateY += evt.deltaY;
evt.preventDefault();
},
});
},
prePage(){
var p = this.pageNum
p = p>1?p-1:this.pageTotalNum
this.pageNum = p
},
nextPage(){
var p = this.pageNum
p = p<this.pageTotalNum?p+1:1
this.pageNum = p
},
password(updatePassword, reason) {
updatePassword(prompt('password is "123456"'))
},
pageLoaded(e){
this.curPageNum = e
},
pdfError(error){
console.error(error)
},
},
components:{
pdf
},
};
</script>
<style>
#app {
font-family: Avenir,Helvetica,Arial,sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 100%;
margin: 0 auto;
overflow: hidden;
min-height: 100vh;
}
.pdf-tab {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 0 .4rem;
-ms-flex-pack: justify;
justify-content: space-between;
}
.pdf-tab .btn-def {
border-radius: .2rem;
font-size: .98rem;
height: 1.93333rem;
width: 6.4rem;
text-align: center;
line-height: 1.93333rem;
background: #409eff;
color: #fff;
margin-bottom: 1.26667rem;
}
.pdf-total {
text-align: center;
font-size: 1.45333rem;
}
.pdf-process, .pdf-total {
text-align: center;
font-size: 1.45333rem;
}
.pdf-num {
margin-bottom: 1.2rem;
}
</style>
下一篇: vue移动端实现excel在线预览
本文地址:https://blog.csdn.net/weixin_45956838/article/details/111831789
下一篇: 九大内置对象及四大作用域