公司的项目是使用vuejs开发的,用到了vant组件库中ImagePreview组件来查看大图,单单只是浏览大图的话确实很好用,如果要加上其他功能就比较繁琐,查看了官方文档,ImagePreview没有提供长按事件以及相对应的方法,社区https://ask.dcloud.net.cn/question/66750也有同胞遇到相同的问题,依旧没有解决,开发时间有限只有曲线解决一下这个问题。
当然,这个问题也可以通过调用原生的浏览大图来解决,由于在我们的项目中和原生交互的接口已经完成,如需新增其他的功能需要进行一轮评审,周期会拉长,所以没有采取该方案,还可以自己实现一套新的浏览大图的方案,这样同样会浪费很长时间,所以就有了接下来的解决方案。
1、在main.js中导入
import { ImagePreview } from 'vant'
2、在查看大图的页面引入该组件,以下代码就是引用的方式,如果还有其他自定的需求可以在template随意发挥
*previewImages是图片源数据,isLoop是标识ImagePreview是否循环滑动,如需了解更多可查看官方文档
<van-image-preview
v-model="isShowPreview"
:images="previewImages"
:loop="isLoop"
@close="onClose()"
>
<template v-slot:index>第{ index }页</template>
</van-image-preview>
3、ImagePreview不支持长按功能,vuejs本身也没有和原生相同的长按事件,通过调用touchstart、touchend、touchmove可以实现类似的功能,用div包裹ImagePreview组件,然后添加@touchstart、@touchmove实现,代码如下
<div class="image-preview" v-if="isShowPreview" @touchstart="touchStart" @touchend="touchEnd">
<van-image-preview
v-model="isShowPreview"
:images="previewImages"
:loop="isLoop"
@close="onClose()"
>
<template v-slot:index>第{ index }页</template>
</van-image-preview>
</div>
4、实现touchStart()方法
touchStart(event) {
this.touchStartX = event.changedTouches[0].clientX // this.touchStartX按下时的横轴坐标
this.touchStartY = event.changedTouches[0].clientY // this.touchStartY按下时的纵轴坐标
console.log(event)
setTimeout(() => {
if (this.isShowPreview) {
this.isLongClick = true // this.isLongClick用于标识是否是长按事件
}
}, 1000)
}
5、实现touchEnd(),该方法主要是为了保证是长按,没有进行滑动操作
touchEnd() {
this.touchEndX = event.changedTouches[0].clientX // this.touchEndX释放时的横轴坐标
this.touchEndY = event.changedTouches[0].clientY // this.touchEndY释放时的纵轴坐标
if (Math.abs(this.touchEndX - this.touchStartX) < 10 && Math.abs(this.touchEndY - this.touchStartY) < 10 && this.isLongClick) {
this.dialogAlert()
this.isLongClick = false
}
}
dialogAlert() { // 该方法是长按弹出的保存图片对话框,用到vant中Dialog组件
Dialog.confirm({
title: '保存图片',
message: '',
cancelButtonText: '取消',
cancelButtonColor: '#007AFF',
confirmButtonText: '确定',
confirmButtonColor: '#007AFF'
}).then(() => {
// do something
})
}
6、ImagePreview的@close实现方法onClose()
onClose() {
this.isShowPreview = false // this.isShowPreview标识PreviewImage是否显示
this.isLongClick = false // this.isLongClick标识是否是长按事件
}
7、总结
实现原理很简单,就是用div包裹一层,然后在外层div上进行操作,讨巧的一个方法,并没有多高深。
当然各个聪明的开发同胞肯定有更好的方法,如果一时没有想到这未免不是一种替代方式,如有更好的方法,希望大家不吝分享,谢谢!