曲线解决van-image-preview长按保存图片

林运浩
2023-12-01

公司的项目是使用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上进行操作,讨巧的一个方法,并没有多高深。

当然各个聪明的开发同胞肯定有更好的方法,如果一时没有想到这未免不是一种替代方式,如有更好的方法,希望大家不吝分享,谢谢!

 类似资料: