资讯专栏INFORMATION COLUMN

记录微信小程序的坑

EastWoodYang / 556人阅读

摘要:除官方外的参考文章微信小程序实例创建下发模板消息实例手把手教你开发微信小程序之模版消息开发教你突破小程序模板消息的推送限制获取用户信息接口的废弃问题接口是获取用户信息昵称,头像等的接口,在官方文档上写是即将废弃。

----------------更新-------------- 2018年10月10日官网3个接口废弃的通知:

1、分享监听接口
分享消息给好友时,开发者将无法从callback获知用户是否分享完成,也无法在分享后立即获得群ID。请参考调整指引

2、getUserInfo接口
用户需要点击组件后,才可以触发登录授权弹窗、授权自己的昵称头像等数据。请参考调整指引

3、openSetting接口
用户需要点击行为后,才可以跳转打开设置页,管理授权信息。请参考调整指引

1.不同版本号是否可以使用某方法/属性

官方文档上提到了几种检测方法,但是测试后发现有些没有用
1)wx.canIUse()对一些api没有用
2)if (wx.apiXX) { wx.apiXX(); }也不完全有用
所以,最后通过直接比较当前版本号和目标版本号来实现兼容。

/**
 * 比较两个版本号的大小,用于兼容小程序不同版本的api时比较版本号(v1 > v2则返回1)
 * @param {*} v1
 * @param {*} v2
 */
export function compareVersion(v1, v2) {
  v1 = v1.split(".")
  v2 = v2.split(".")
  var len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push("0")
  }
  while (v2.length < len) {
    v2.push("0")
  }

  for (var i = 0; i < len; i++) {
    var num1 = parseInt(v1[i])
    var num2 = parseInt(v2[i])

    if (num1 > num2) {
      return 1
    } else if (num1 < num2) {
      return -1
    }
  }

  return 0
}

const  SDKVersion  =  wx.getSystemInfoSync().SDKVersion; // 获取版本
if(T.compareVersion(SDKVersion, "2.0.7")>=0) { ... }
2.小程序间的跳转

小程序跳转只能实现 同一公众号下关联 的小程序跳转
一个公众号可关联10个同主体的小程序,3个不同主体的小程序。
一个小程序可关联3个公众号。
p.s. 所以想跳转像苏宁小程序,只能把我们小程序关联到他们小程序的公众号下)

(1)使用navigator组件(仅用于微信2.0.7以上版本)


跳转mp

(2)使用navigateToMiniProgram来兼容微信2.0.7以下(但即将废弃) >=1.3.0

goMiniprogram() {
    const  SDKVersion  =  wx.getSystemInfoSync().SDKVersion; // 获取版本
    if(T.compareVersion(SDKVersion, "2.0.7")>=0) {
        wx.navigateToMiniProgram({
            appId:  this.changeNewAppid,
            path:  this.changeNewUrl,
            envVersion:  "release",
            success(res) {
                console.log("打开mp成功")
            }
        })
    }
}

调试注意:
开发者工具上不会显示跳转,但我们可以从回调函数里log打印信息,只有真机调试才可以跳转

3.小程序所属的公众号入口及其推送文章等入口进入小程序的url配置

格式:pages/list?source=wxmpcz01 (不要appid,也不要pages前加/

4.保存图片功能(用途之一是分享朋友圈)

思路:
1.小程序不能分享到朋友圈,只能通过保存图片的形式分享。
2.如果保存静态图片,可以直接调接口就行,但是需求是动态的图片(获取用户的头像),所以需要用canvas画图,然后保存成2倍/3倍图

优化的问题:
一、文字有用特殊字体,但是字体文件都比较大。所以需要用fontmin抽取出所需字的字体文件,最后上线页面从原来的3.7MB变成29KB字体woff/eot/ttf文件。

之前产品想要文案不写死,三种成功页各自有随机的文案,这个在想怎么优化更好。因为写死的文案可以直接抽出来。随机文案要么就是一次性把文案抽出来但字体文件大小会增加;要么就是node写个进程模拟cmd去跑fontmin实时压缩字体的命令,但这种会更慢一些,而且小程序不一定支持这种写法。(一般的PC端网页是支持的)

小程序中canvas不支持使用自定义字体。所以保存功能需要使用图片替代文字。

保存图片因为用的canvas,然后canvas每一层无法设置优先级,只能一层层叠上去,所以一些图片/资源异步加载的顺序比较重要,如果加载顺序不做控制则可能将其他内容物覆盖。目前用的是await/aync + Promise.all()来实现

二、为了使保存的带有二维码的图片更加清晰,保存图片需要使用upng转换成base64格式的。

5.canvas画图

1.canvas的clip()裁剪方法,只对第一次裁剪的图有效,后面裁剪都无效。
解决方案:制作一张和头像图片一样大的中间有个n个圆形镂空(中间透明)的图片绘制在头像上,在视觉上给头像做出圆形的效果。
2.不能给文字设置字体,所以需求需要特殊字体时用的图片。
3.保存canvas为图片时,ctx.draw()需要加个定时器,晚些执行canvasToTempFilePath().否则保存下来的是空白图片。

ctx.draw(true, setTimeout(function() { // 延迟一下
    wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 2079,
        height: 2181,
        destWidth: 2079,
        destHeight: 2181,
        canvasId: "myCanvas",
        success: function(res) {
            self.data.savedImgUrl = res.tempFilePath;
            self.saveImageToPhoto();
        }
    });
}, 400));
// 保存图片到相册
saveImageToPhoto() {
    const that = this;
    if (this.data.savedImgUrl !== "") {
        wx.saveImageToPhotosAlbum({
            filePath: this.data.savedImgUrl,
            success: function() {
                that.imgSaveLoading = false;
                that.$apply();
                wx.showModal({
                    title: "保存图片成功",
                    content: "xxxx",
                    showCancel: false
                });
            },
            fail: function(res) {
                console.log(res);
                that.imgSaveLoading = false;
                that.$apply();
                if (res.errMsg === "saveImageToPhotosAlbum:fail cancel") {
                    wx.showModal({
                        title: "保存图片失败",
                        content: "您已取消保存图片到相册!",
                        showCancel: false
                    });
                } else {
                    wx.showModal({
                        title: "提示",
                        content: "保存图片失败,您可以点击确定设置获取相册权限后再尝试保存!",
                        complete: function(res) {
                            if (res.confirm) {
                                wx.openSetting({});      // 打开小程序设置页面,可以设置权限
                            } else {
                                wx.showModal({
                                    title: "保存图片失败",
                                    content: "您已取消保存图片到相册!",
                                    showCancel: false
                                });
                            }
                        }
                    });
                }
            }
        });
    }
}

参考文章:
小程序05 canvas绘图并保存到相册
canvas坑

6.分享转发功能

如果使用右上角的默认分享功能,可以调用onShareAppMessage(), 如果自定义按钮分享则是使用 onShareAppMessage(res) { let shareType = "friend"; let title = "送你一个公益礼包,快去打开看看是什么!"; let path = "XXXX"; // 右上角分享时 if (res.from === "button") {// 来自页面内转发按钮,根据不同的#id分享不同的链接等操作 shareType = res.target.id.split("-")[1]; if (shareType === "family") { // 分享结果页 path = ‘XXXXXX2’; title = "我有个公益礼包需要和家人一起打开,你快点进来!" ; } .... } return { // 分享的title,path里都可有变量 title: title, path: path, imageUrl: "xxx", success(res) { console.log(res); 做一些成功后的操作... }, fail(res) { console.log(res); } }; } 7.上报formid给后台实现服务消息触达

1.在微信公众平台-小程序的模板中心先申请一个消息模板
2.服务消息触达只有支付的和提交表单才能触发服务触达通知。而支付这个方法不符合场景,所以使用提交表单:把任意一个文本改造成一个空表单的按钮,然后点击上报formid给后台。(1次提交表单可下发1条,多次提交下发条数独立,相互不影响。)
3.后台使用formid后调用相应触达的接口。

/**
前提条件:
1.已获取access_tocken。
(参考接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret})
2.已获取openId。
(参考接口:https://api.weixin.qq.com/sns/jscode2session?appid=${G.appId}&secret=${ appSecret}&js_code=${code}&grant_type=authorization_code)
**/

// 关键代码:
formSubmit(e) { const { formId } = e.detail; // 获得formid ... },

注意:
1.只能手机调试,我用开发工具打印出来的formId: "the formId is a mock one"并不是数字串。
2.每个formid只能给当前用户推送的时候用 不能给其他人用。

除官方api外的参考文章:
微信小程序实例:创建下发模板消息实例
手把手教你开发微信小程序之模版消息
开发 | 教你突破小程序模板消息的推送限制

8.获取用户信息接口wx.getUserInfo的废弃问题

wx.getUserInfo接口是获取用户信息(昵称,头像等)的接口,在官方文档上写是即将废弃。现在开发版和体验版已经废弃(调用接口默认直接fail),但是现网版本还是可以使用(会出现系统弹弹窗),官网更新说于2018/10/10废弃
目前,有两种兼容方式:
1.如果只是单纯展示用户头像或昵称,可以使用 组件。但是这个有局限性,只能显示,却获取不到信息,比如:后台接口需要前端传递用户昵称或头像信息时。

2.使用绑定的点击事件openSettingFn还是可以调用api**

// 写法1

openSetting(e) {
  //判断是否获得了用户地理位置授权(v2.0.7以上版本)
  const that = this;
  if(e.detail.authSetting["scope.userLocation"]) { 
    //同意用户的地理位置授权 立刻打开“设置”
    const getUserLocationWrapper = function(){
      API.getUserLocation().then((location)=>{
        ...
      }).catch((error) => {
        console.log("发起api 失败",error)
      });
    }
    // 设置一个延时 因为用户打开授权按钮不能立即生效 所以会出现请求接口auth deny的问题
    setTimeout(getUserLocationWrapper, 500);
  }
}

// 写法2

  自动获取地址


dealLocationAuthorize() {
  //判断是否获得了用户地理位置授权(v2.0.7以下版本)
  wx.getSetting({
    success: (res) => {
      if (!res.authSetting["scope.userLocation"]){
        this.openConfirm()
      }
    }
  })
}

// 未授权地址时,需要打开自定义的弹窗,询问用户是否去设置中打开权限
openConfirm () {
  const that = this;
  //此处可以打开一个modal询问,然后在success的回调里调用openSetting都行的
  //wx.showModal({
    //content: "XXXX要获取您的地理位置,是否允许?",
    //confirmText: "允许",
    //cancelText: "不允许",
    //success: function (res) {
      //if (res.confirm) { //点击“确认”时打开设置页面
      
        wx.openSetting({ // openSetting打开“设置”(v2.0.7以下版本)
          success: (res) => {
            const getUserLocationWrapper = function(){
              API.getUserLocation().then((location)=>{
                ...
                console.log("调用后台接口拿到位置信息", location)
              }).catch((error) => {
                console.log("发起调用后台接口失败",error)
              });
            }
            // 设置一个延时 因为用户打开授权按钮不能立即生效 所以会出现请求接口auth deny的问题
            setTimeout(getUserLocationWrapper, 500);
          }
        })
        
      //} else {
       // console.log("用户点击取消")
      //}
      //that.$apply();
    //}
  //});
}
12.有时候开发者模式自测通过,但是发的体验版一些数据拿不到,然后当体验版开了调试模式时,又可以跑通所有逻辑。

解决过程:后来发现是请求方式的问题,dev环境都是http请求,idc则需要https的请求,所以之前只有开了调试模式才能拿到数据。然后,还发现因为调试者工具上开发时默认勾选“不校验合法域名、https证书...”的选项所以开发时未报错,如果取消勾选则会报http那个域名不在白名单内报错(我们小程序白名单用的是https的url)。

还发现了一些奇怪的现象:
像小程序开发板/体验版开了调试模式,再去打开线上小程序,本没有调试工具的线上小程序也有了调试工具。以及这三个版本小程序的缓存感觉有一定联系,可能共用。具体待实验后跟进。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97868.html

相关文章

  • 从零开始:信小程序新手入门宝典《一》

    摘要:为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习一微信小程序的特点张小龙张小龙全面阐述小程序,推荐通读此文小程序是一种不需要下载安装即可使用的应用,它出现了触手可及的梦想,用户扫一扫或者搜一下即 为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习; 一:微信小程序的特点 张小龙:张小龙全面阐述小程...

    whataa 评论0 收藏0
  • 从零开始:信小程序新手入门宝典《一》

    摘要:为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习一微信小程序的特点张小龙张小龙全面阐述小程序,推荐通读此文小程序是一种不需要下载安装即可使用的应用,它出现了触手可及的梦想,用户扫一扫或者搜一下即 为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习; 一:微信小程序的特点 张小龙:张小龙全面阐述小程...

    mdluo 评论0 收藏0
  • 从零开始:信小程序新手入门宝典《一》

    摘要:为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习一微信小程序的特点张小龙张小龙全面阐述小程序,推荐通读此文小程序是一种不需要下载安装即可使用的应用,它出现了触手可及的梦想,用户扫一扫或者搜一下即 为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习; 一:微信小程序的特点 张小龙:张小龙全面阐述小程...

    LdhAndroid 评论0 收藏0

发表评论

0条评论

EastWoodYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<