对应vue版本为2.5.2

前言:

  • 一个很普通的上传图片预览功能,使用vant-uploader实现
vant-uploader api传送门

在pc端模拟h5,以及在ios手机扫码Ip访问本地均没任何问题;但是在安卓上出现了bug:在第一次上传图片以及预览很Ok,没问题,但是在页面回退2级以后,再重新进入,上传图片没问题,叮当 点击预览,页面只展示了蒙版,图片没用预览成功。。。

但是神奇的是,当我一番操作,重现;发现一个怪异问题,就是在回退2级以后再回来上传图片,当我上传2张的时候,oh my god,可以成功预览了。。。

这个时候老司机有了一点思路,是否是因为存储图片的array没有更新,被缓存住了导致第二次上传2张的时候更新了array,又可以了呢

有了初步想法,上去就是一顿操作

1.页面销毁的时候重置下img的array

beforeDestroy() {
    this.imgArray = [];
}

2.初始化的时候再重置下

created() {
    this.imgArray = [];
}

毫无疑问,这些操作没有达到效果,依旧不行

由于觉得可能是缓存引出的问题,所以又有了新一轮的想法:

尝试给url添加时间戳

于是去node_modules 看了看vant的源码,并开始打断点调试,

找到了vant 下面的 uploader 并在onPreviewImage方法里面给图片的url加上时间戳

var imageContents = imageFiles.map(function (item) {
    return (item.content || item.url) + '&timer=' + new Date;
  });

继续验证,卒。。

重新整理思路,这个时候想到了一个骚操作,既然第二次的时候上传2张图片就行,是不是可以模拟下,先达到实现功能

于是开始一桶撸代码,

imageArray.unshift(1);
imageArray.shift()
imageArray.splice()
...

依然无效。。。在做了这么多无用功后,有点没有头绪了。

笔者开始求助大佬了,

嗨,大佬:。。。

我们重新整理思路,还是把问题定位到vant 模块上,

  • 首先我们定位图片的url有没有丢失,于是在源码中加了很多日志,发现url一直在,没有丢失现象
  • 接着继续定位,url没有丢失,又没办法预览到,是不是预览的时候出问题了呢
return h(SwipeItem, [
  h(
    "div",
    {
      style: {
        color: "#ff0000",
      },
    },
    [image]
  ),
  h(Image, {
    attrs: {
      /*  */ src: image,
      fit: "contain",
    },
    class: bem("image"),
    scopedSlots: imageSlots,
    style: index === _this4.active ? _this4.imageStyle : null,
    nativeOn: {
      touchstart: _this4.onImageTouchStart,
      touchmove: _this4.onImageTouchMove,
      touchend: _this4.onImageTouchEnd,
      touchcancel: _this4.onImageTouchEnd,
    },
  }),
]);

找到图片预览模块 image-preview 的 imagePreview.js 在生成预览图片的时候,放了个空div并且把url塞进去,再次操作发现图片url也是正常显示的。

  • 这个也没有问题,进一步定位,是不是动态生成image的时候出了问题或者是样式出了问题
return h(
  Swipe,
  {
    ref: "swipe",
    attrs: {
      loop: this.loop,
      indicatorColor: "white",
      duration: this.swipeDuration,
      initialSwipe: this.startPosition,
      showIndicators: this.showIndicators,
    },
    class: bem("swipe"),
    on: {
      change: this.setActive,
    },
  },
  [
    this.images.map(function (image, index) {
      return h(SwipeItem, [
        h("img", {
          style: {
            width: "12rem",
            height: "12rem",
          },
          attrs: {
            src: image,
          },
        }),
      ]);
    }),
  ]
);

奇迹出现了,妈呀,竟然可以了,喜极而泣。。。。
问题就此定位在image这个模块上了

  • 继续定位image模块,在watch, render, onload一些地方都加上了日志,没定位到问题点,又犯难了
  • 由于项目着急,选择了一种粗暴的办法解决了问题
return h("img", _mergeJSXProps2([{
    "attrs": {
      "src": this.src
    },
    "style": {
        width: "36rem"
    },
    "on": {
      "load": this.onLoad,
      "error": this.onError
    }
}, imgData]));

在image模块给image强制植入一个width,就可以解决以上问题

路过的大佬如果有更好的解决办法可以留言,我必膜拜改正

码农进阶题库,每天一道面试题 or Js小知识 https://www.javascriptc.com/interview-tips/

❤️ 看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!

关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网 - 前端进阶资源教程 www.javascriptC.com
一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
JS中文网 - 前端进阶资源教程,领略前端前沿,关注IT平头哥联盟

Mark
52 声望4 粉丝

用心分享,做有梦想的攻城狮;