前端APP原生实现适配苹果安卓手机附件上传功能

我这里是循环出多个上传对象,样式已经简化

       <span
            v-for="(item, index) in attachInfoList"
            :key="index + '-wrap'"
            //设置捕获事件.
			//当一个父元素div1 包裹着一个子元素div2 同时有点击事件。
			//我们希望点击从外面执行到里面,先触发父元素再触发子元素。
			//我们可以在父元素的点击事件加上@click.capture
            @click.capture="changeCurImage(index)"
          >
            <img
              @click.stop="showChooseMethod"
              :src="item.showImage"
            />
            //由于安卓手机适配问题,没有自带拍照功能,所以需要自己写一个选择弹窗
            //来和苹果手机保持一致
            <div v-if="item.isShowChoose">
              <ul>
                <li @click="uploadFileMethod" class="choose-div-li">
                  <span> 相册 </span>
                </li>
                <li @click="makePhotoMethod" class="choose-div-li">
                  <span> 拍照 </span>
                </li>
                <li @click="uploadFileMethod" class="choose-div-li">
                  <span> 浏览 </span>
                </li>
              </ul>
            </div>
            //上传文件的input元素,注意accept="*.*",从而支持所有类型文件
            <input
              ref="uploadFile"
              type="file"
              @change="onImageChange($event)"
              accept="*.*"
            />
            //此input元素为了支持上面提到的安卓拍照上传功能
            //注意capture="camera"和accept="image/*"
            <input
              ref="uploadPhoto"
              capture="camera"
              type="file"
              accept="image/*"
              @change="onImageChange($event)"
            />
            <div >{{ item.fildName }} </div>
          </span>

下面是各个方法

   import lrz from 'lrz';
   changeCurImage(index) {
	     //记录当前点击的input元素序号
	      this.curImageIndex = index;
   },
    onImageChange(event) {
      if (event.target.files[0].type.indexOf('image') != '-1') {
        //说明上传的是图片
        this.attachInfoList[this.curImageIndex].file = event.target.files;
        //将图片内容进行压缩
        lrz(this.attachInfoList[this.curImageIndex].file[0], {
          width: 1000,
        })
          .then((res) => {
            //得到压缩后的图片base64编码
            this.attachInfoList[this.curImageIndex].showImage = res.base64;
            let file = [{url: res.base64,file: { name: res.origin.name,},},];
            //调用后端上传文件接口
            this.uploadChange(file);
          })
          .catch((error) => {
            //失败清除数据
            this.attachInfoList[this.curImageIndex].file = [];
            this.attachInfoList[this.curImageIndex].successFile = {};
            this.$toast('文件压缩失败' + error);
          });
      } else {
        //说明上传的是文件,由于后端接口限制,需要将图片转化成base64编码
        var files = new File(event.target.files, 'r');
        this.attachInfoList[this.curImageIndex].file = event.target.files;
        var reader = new FileReader();
        reader.readAsDataURL(files);
        reader.onload = () => {
          // 文件转换为base64格式
          let file = [{url: reader.result,file: {name: event.target.files[0].name,}, },];
          //调用后端上传文件接口
          this.uploadChange(file);
        };
        reader.onerror = function (error) {
          this.$toast.fail('文件转换失败,请稍后再试');
        };
      }
    },
    uploadChange(file) {
      this.$http.uploadBase64(file).then((res) => {
          this.attachInfoList[this.curImageIndex].successFile = res;
          this.$toast('文件上传成功');
        })
        .catch((msg) => {
          this.attachInfoList[this.curImageIndex].file = [];
          this.attachInfoList[this.curImageIndex].successFile = {};
          this.$toast.fail('文件上传失败');
        });
    },
    showChooseMethod() {
       //如果是ios系统,则采用原生方法
       if (this.isiOS) {
         this.$nextTick(() => {
         //ios系统显示原生弹框,所以将自己写的隐藏
          this.attachInfoList[this.curImageIndex].isShowChoose = false;
          //选中dom元素并且触发click事件
           this.$refs.uploadFile[this.curImageIndex].click();
         });
      } else {
          //如果是安卓系统,则显示自己写的弹框
          this.attachInfoList = this.attachInfoList.map((item) => {
            item.isShowChoose = false;
            return item;
          });
          this.attachInfoList[this.curImageIndex].isShowChoose = true;
    },
    //点击相册和浏览时,隐藏选择弹框,触发普通上传input元素
    uploadFileMethod() {
      this.$nextTick(() => {
        this.attachInfoList[this.curImageIndex].isShowChoose = false;
        this.$refs.uploadFile[this.curImageIndex].click();
      });
    },
    //点击拍照时,隐藏选择弹框,触发capture="camera"的input元素
    makePhotoMethod() {
      this.$nextTick(() => {
        this.attachInfoList[this.curImageIndex].isShowChoose = false;
        this.$refs.uploadPhoto[this.curImageIndex].click();
      });
    },

目前只是在文件中使用,还未封装成组件,但是基本功能都实现啦

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值