模拟实现图片长按保存功能

关于图片的长按保存(原生代码暂未集成,先记录一下准备工作)

最近要实现图片的长按保存功能,百度了好多,单由前端实现的方法网上也有,不过看上去好麻烦,头疼,后来有看到博文说原生实现会简单些,咨询了老板,说原生可以实现的,我需要提供所选中图片的url,这样那就简单多了
理一下流程:页面有一个图片轮播效果,点击某一张图片,实现图片预览的功能,在此基础上长按进行图片的保存到本地,因为有好几处都用到了这个功能,所以把它封装成了个组件,完整代码看最后
声明:图片预览我引用了vant库的imgPreview

父组件:

1,引入子组件

import imgPreview from "../../comps/common/imgPreview";

2,data里首先定义了showPreview值为false

showPreview:false,  // 图片预览组件标志符

3,在父组件图片轮播部分设置一个函数,点击这部分让showPreview值变为true,继而触发自己封装的图片预览组件,我的代码如下,仅供参考

<mslider :loop="isLoop" :show-dot="true" ref="slider" :auto-play="false">
  <div class="img_wrapper" v-for="(item,index) in showImgs" :key="index">
    <img :src="item" alt="" @click="getImg(index)" loaded @load="imgLoad">
  </div>
</mslider>
// 对应的methods方法
getImg(index){
  this.showPreview = true;
}

4,showPreview为true,应用子组件

父组件要传给子组件的值有两个
showPreview:是否显示图片预览组件,不出意外,绝对为true
showImgs:要传过去的预览图片的数组

<imgPreview v-if="showPreview" :imgList = showImgs @func="changePreview" :isShowPreview = showPreview></imgPreview>
// methods里面的方法,接受子组件传递过来的值并进行赋值,即子传父触发的方法
changePreview(val){
  // console.log(">>>>>>>>>>>>>>>>>>>>",val);   // 不出意外,绝对为false
  this.showPreview = val
},

子组件

子组件不能直接改动父组件传过来的值,不然会报错,这里就另外声明了一个值flag,在子组件代替showPreview进行操作

子组件完整代码如下:

<template>
  <!-- 图片预览 -->
  <div id="imgPreview" >
    <!-- 图片预览模块,利用touchstart,touchend模拟了一下长按事件 -->
    <div v-if="flag" @touchstart="touchStart" @touchend="touchEnd">
      <van-image-preview v-model="flag" :images="imgList" @change="onChange"> </van-image-preview>
    </div>
	
    <!-- 这里引用了vant的分享模块,长按弹出分享列表,里面可以自行设置选项,分享到微博,微信,盆友圈,下载本地等 -->
    <van-share-sheet
      v-model="showShare"
      :options="options"
      @select="onSelect"
      :duration="0.1"
    />

  </div>
</template>
<script>
import { Toast } from 'vant';
export default {
  name:'',
  props:['imgList','isShowPreview'],
  data(){
    return {
      flag:this.isShowPreview,    // 子组件不能改动传过来的值,不然会报错,这里就另外声明了一个值,在子组件进行操作
      index:1,
      showShare:false,    // 分享模块的显示与否
      options: [
        { name: '微信', icon: 'wechat' },
        { name: '朋友圈', icon: 'https://img.yzcdn.cn/vant/custom-icon-fire.png' },
        { name: '微博', icon: 'weibo' },
        { name: '下载', icon: 'https://img.yzcdn.cn/vant/custom-icon-light.png' },
      ],
      touchStartX:null,
      touchStartY:null,
      touchEndX:null,
      touchEndY:null,
      touchstartTime:null,
      touchendTime:null,
      duration:0,
      
      curImgSrc:null,
      osType:null,
    }
  },
  created(){
	console.log(this.flag,this.isShowPreview)   // 首次传过来的值必定未true
	this.curImgSrc = this.imgList[0];  // 获取第一张图片src并进行赋值
    console.log("this.curImgSrc>>>>>",this.curImgSrc);
    // 判断设备型号
    let u = navigator.userAgent
    let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
    let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
    console.log("isAndroid>>>>",isAndroid,"------","isIOS>>>>>>",isIOS)
    if(isAndroid){
      this.osType = 'Android';
    }
    if(isIOS){
      this.osType = 'ios';
    }
    console.log("this.osType---65-----",this.osType)
  },
  mounted(){

  },
  methods:{
    onChange(index) {
      this.index = index;
      // console.log("change>>>>>>>>>>>>>",index)
      // 要根据当前的index值获取到对应图片的src,长按保存图片时将该src当作参数传过去
      // console.log("当前选中的图片的src",this.imgList[index])   // 这里可以拿到图片的src
    },
    // 选择分享模块的某个功能所执行的操作,我这边因为目前原生代码暂未集成,只是做了一个简单的toast操作
    onSelect(option) {
      // Toast(option.name);
      if (this.osType == 'Android') {
        // Android   安卓机
     	// 安卓机代码还未集成
        console.log("安卓机")
      }
      if (this.osType == 'ios'){
        // ios  苹果机
        if(option.name == '下载'){
          console.log("下载图片")
          console.log("this.curImgSrc>>>>>下载",this.curImgSrc)
          console.log("苹果机");
          console.log(window)  // 电脑打印window是没有webkit属性的,要在ios设备上进行测试,我是在苹果电脑的模拟机上进行测试的
          console.log(window.webkit)  // 电脑打印window
          //下面是苹果机调用原生方法,JsCallObjectC是后台定义好的方法,要传递的参数你们自己商量好,其他的都是固定格式,套着用就好
          // window.webkit.messageHandlers.JsCallObjectC.postMessage('{"methodName":"SaveImage","ImgUrl":"'+this.curImgSrc+'"}');          
          window.webkit.messageHandlers.JsCallObjectC.postMessage('{"methodName":"SaveImage","ImgUrl":"https://www.wuyoumaicai.com/image/logo.png"}');
          // 苹果原生下载图片仅支持https,目前动态获取的的图片的src是http格式的,所以现在是传了个https格式的一个定死的图片,之后再更新

        }else if(option.name == '微信'){
          console.log("分享到微信")
          console.log("this.curImgSrc>>>>>分享到微信",this.curImgSrc)
        }
      }
      this.showShare = false;
    },
    touchStart(event) {
      this.touchstartTime = new Date().getTime();
      this.touchStartX = event.changedTouches[0].clientX // this.touchStartX按下时的横轴坐标
      this.touchStartY = event.changedTouches[0].clientY // this.touchStartY按下时的纵轴坐标
    },
    touchEnd() {
      this.touchEndX = event.changedTouches[0].clientX // this.touchEndX释放时的横轴坐标
      this.touchEndY = event.changedTouches[0].clientY // this.touchEndY释放时的纵轴坐标
      this.touchendTime = new Date().getTime()
      this.duration = this.touchendTime - this.touchstartTime
      // console.log("间隔时间为",this.duration)

      // 非左右滑动
      if (Math.abs(this.touchEndX - this.touchStartX) < 10 && Math.abs(this.touchEndY - this.touchStartY) < 10) {
        if(this.duration >= 800){
          // 时间大于800毫秒,长按
          // console.log("非左右滑动时间大于800毫秒,长按")
          this.showShare = true;   // 分享模块显示出阿来
        }else{
          // 时间小于800毫秒,单纯的点击事件
          // console.log("非左右滑动时间小于800毫秒,单纯的点击事件")
          this.flag = false;
          this.showShare = false;
          // this.$emit('func',this.flag)   // 同下一行
          this.$emit('func',false)    // 子组件修改父组件传递过来的值并返回给父组件
        }
      }else{
        // 左右滑动
        if(this.duration >= 800){
          // 时间大于800毫秒,单纯的点击事件
          // console.log("左右滑动时间大于800毫秒,单纯的点击事件")
          this.flag = true;
          this.showShare = false;
        }else{
          // 时间小于800毫秒
          // console.log("左右滑动时间小于800毫秒,隐藏分享/下载按钮")
          this.flag = true;
          this.showShare = false;
          // this.$emit('func',false)
        }
      }
    },
  }
}
</script>
<style lang="less" scoped>
  #imgPreview{
    width:100%;
  }
</style>

不是尽善尽美,有啥不足,欢迎不吝赐教

调用原生接口参考链接如下:
https://www.jianshu.com/p/c35b12ffc0f1
https://blog.csdn.net/BennyShi1998/article/details/79402289/
https://blog.csdn.net/Chris__wang/article/details/103144680

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值