vue开发微信活动中遇到的坑

前端之家收集整理的这篇文章主要介绍了vue开发微信活动中遇到的坑前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

需求背景

前段时间接到PM需求,要做一个微信端的问答+奖励金类活动,大概需求如下:

  1. 首先参与活动需要用户微信授权登录用户每天默认的答题次数有限,要增加答题机会可分享给好友,好友参与答题了就会给用户增加1-2次机会。
  2. 首页:活动首页展示了用户目前的总奖励金额及剩余的答题次数,可通过首页进入答题页、好友排行榜、游戏规则等。
  3. 排行榜页面展示参与了答题的好友列表,列出了好友的答题成绩及排行。
  4. 答题页:有若干题目,全部答完后提交答案,跳转至结果页。
  5. 结果页:展示用户当次答题分数及奖励金,有几个按钮,再次答题、分享、去论坛看答案,下载app提现,其中论坛和下载都是外链
  6. 分享页:一张图片,展示了用户头像和昵称,以及本次答题的分数、奖励金、二维码和一些其他文案,用户通过长按图片图片分享给好友或朋友圈,好友通过图片中的二维码参与活动。

相关技术

  1. 架构:vue+vue-router+vuex+axios全家桶
  2. 二维码:qrcode.vue
  3. 画图: html2canvas
  4. 其他工具

需求和技术全部列出来了,一目了然,简单明了
具体的实现细节就不描述了,上面的需求背景中也忽略了一些其他(app内打开,与app的一些交互,微信右上角分享注册提现等等),不是重点。

下面介绍一下开发过程中踩到的坑:

  1. 使用html2canvas画出的待分享图片(以下统一称分享图),模糊失真。
  2. 分享图不完整,或画图失败、或缺失头像、或整体黑色
  3. 微信ios端长按分享图,只弹出的「保存图像」和「取消」,并没有我们需要的「发送给朋友」和「识别二维码

解决方案:

  1. html2canvas画的图片失真有两个因素:

    • 高分屏下canvas元素尺寸设置,这个就不多说了,很常见的问题,直接上码
    function html2Image(dom) {
        return new Promise(function(resolve,reject) {
        function getPixelRatio(context) {
          let backingStore = context.backingStorePixelRatio ||
            context.webkitBackingStorePixelRatio ||
            context.mozBackingStorePixelRatio ||
            context.msBackingStorePixelRatio ||
            context.oBackingStorePixelRatio ||
            context.backingStorePixelRatio || 1;
          return (window.devicePixelRatio || 1) / backingStore;
        };
        let shareContent = dom; //需要绘图的DOM对象
        let width = shareContent.offsetWidth; //dom 宽度
        let height = shareContent.offsetHeight; //dom 高度
        let canvas = document.createElement("canvas"); //创建一个canvas节点
        let context = canvas.getContext('2d');
        let scale = getPixelRatio(context);
    
    // 这个地方是处理模糊问题的关键
    canvas.width = width * scale;
    canvas.height = height * scale;
    context.scale(scale,scale);
    
    // <a href="/tag/guanbi/" target="_blank" class="keywords">关闭</a>抗锯齿
    context.mozImageSmoothingEnabled = false;
    context.webkitImageSmoothingEnabled = false;
    context.msImageSmoothingEnabled = false;
    context.imageSmoothingEnabled = false;
    
    let opts = {
      scale: scale,// <a href="/tag/tianjia/" target="_blank" class="keywords">添加</a>的scale 参数
      canvas: canvas,//<a href="/tag/zidingyi/" target="_blank" class="keywords">自定义</a> canvas
      logging: false,//日志开关,便于查看html2canvas的内部执行流程
      width: width,//dom 原始宽度
      height: height,backgroundColor: null,// 设置null,透明背景
      useCORS: true // 【重要】开启跨域配置
    };
    // html2canvas
    html2canvas(shareContent,opts).then((canvas) => { 
      // 这里用到了canvas2image组件
      var img = convertToImage(canvas,canvas.width,canvas.height,'image/jpeg');
      resolve(img);
    })

    })
    }

    • 绘制的目标dom中有背景图片
      图片最好作为img元素放进目标dom中,不要作为样式background,不然绘出的图片肯定要模糊
  2. 图片绘制不完整,是由于图片尚未加载完成,或者dom元素没有load结束就开始绘图

  3. 微信ios下长按菜单没有「发送给朋友」和「识别二维码

    • 这算是微信的一个坑(以下所说的微信统一指ios下,安卓没有这个问题),因为项目中用到了vue-router,且router.mode='history',使用history作路由跳转的时候,微信的坑比较多,其中分享的时候报“invalid signature”签名错误是比较常见的,这个问题的处理方法一般是,每个页面在请求签名的时候统一使用首次进入时候的url,具体做法可自行Google/百度。按理说页面通过wx.config({...})注册成功后,相关功能都应该可以正常使用的,但是长按菜单还是有问题,不明所以,已经在GitHub上给weixin-js-sdk提(issue)[]了,目前尚未解答。下面介绍一下解决方案。
    • 进入分享页面的时候,不使用router跳转
      具体做法是将点击跳转的行为,主要是vm.$router.push()改为或者location.href='xxx',这样做就是完全避开router,相当于重新打开一个页面,但是这样做有个很明显的缺点,分享页相当于新页面,那么存储在vuex store中的状态就取不到了,如果需要带参数到分享页,可以带在href跳转链接上,或者暂存在localStorage里
    • 将history模式改为hash
      因为微信做url认证的时候是忽略#以后的部分的,所以hash模式刚好可以完美的解决这个问题

      new Router({
          mode: 'hash',//这里默认值就是hash,可以省掉
        //...
      }) 

总结

个人微信项目经验不多,仅做记录,也希望对他人能有所帮助。相信这些问题或多或少也有人遇到过,应该也有更有效更优雅的解决方案。如有问题,请多多指教~

猜你在找的微信小程序相关文章