最近在作公司的小程序项目时,须要作一个充值页面,打算直接复用微信公众号上已经开发好的H5页面,谁知在本地真机调试的时候调到H5页面可以支付成功,可是提到体验版和正式版后发现不能调起微信支付,最后查了不少文档发现小程序的web-view不支持微信支付,只能经过跳回小程序调用小程序支付的API。实现大致思路:在H5页面获取支付参数,而后判断是否在小程序环境中,若是在,获取到支付参数后返回到小程序并将支付参数传给小程序,小程序调用wx.requestPayment(OBJECT)接口完成支付,须要注意的是,获取支付参数的appId为小程序的appId.下面是个人实现方式:html
在小程序发布到线上以后发现有些新用户在登陆页面卡死,最后发现是没有获取到unionId,为何获取不到unionId呢,看下微信对UnionId机制的原文解释:
若是开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可经过unionid来区分用户的惟一性,由于只要是同一个微信开放平台账号下的移动应用、网站应用和公众账号(包括小程序),用户的unionid是惟一的。换句话说,同一用户,对同一个微信开放平台下的不一样应用,unionid是相同的。
同一个微信开放平台下的相同主体的App、公众号、小程序,若是用户已经关注公众号,或者曾经登陆过App或公众号,则用户打开小程序时,开发者能够直接经过wx.login获取到该用户UnionID,无须用户再次受权。
注意: 后边这句话的描述
用户关注过公众号,或者曾经登陆过App或公众号,则用户打开小程序时,开发者能够直接经过wx.login获取到该用户UnionID
即:若是用户没有关注过公众号,或者没有登录过App,经过wx.login是没法获取到该用户UnionID,只能经过wx.getUserInfo来获取UnionId
经验证,系统不存在UnionId的小程序用户都是没有关注公众号或未在App中使用微信受权的用户
解决方案:
获取小程序UnionId获取不到时,wx.getUserInfo能够获取敏感数据,其中包含UnionId字段。
实现:参考https://www.cnblogs.com/cai-r...连接描述web
(使用该功能,小程序必须已是已发布状态)小程序提供了扫描普通二维码跳转小程序的功能,首先在微信公众平台配置二维码规则,域名路径必须是校验文件所在路径,能够配置测试连接进行测试,能够配置最多5个测试连接,能够指定测试连接打开的测试范围(开发、测试、正式),必须是具备体验权限的用户才能够进行测试,非体验用户进入正式版本。规则发布后,配置符合规则的连接都可进入到小程序。json
小程序官方组件movable-area、movable-view说明canvas
刚开始作这个可拖拽元素的时候,是准备将其作成一个组件,在每一个须要的地方引入便可,可是有一个很大的问题就是所在页面有一个canvas生成的二维码,原生组件在小程序中的层级是最高的,即无论怎么布局或者给z-index都是不生效的,因此拖拽元素拖拽过程当中会在二维码下面。
解决这个问题的过程当中遇到了不少坑,首先想到的是小程序中有没有直接生成二维码图片的插件,有是有,可是个人字符串太长了,生成的base64编码均太长了,因此我仍是用的weapp-qrcode.js插件,这个插件自带导出图片的方法,用的就是wx.canvasToTempFilePath将画布导出生成图片,页面上canvas所在位置放置一个image组件,将canvas移到可视区域外面,可是生成的图片一直是乱的,原来是我没给canvas样式的高度和宽度致使生成出现问题,可是这样仍是在一些安卓机上出现问题,调用wx.canvasToTempFilePath已是在draw回调以后了,可是仍是须要给延时才能够,在这里我给的500ms,基本上就能够了。
原生组件层级最高的问题解决了,可是又出现一个问题,就是可拖拽元素是一个组件,所在页面又有不少按钮,若是直接将可拖拽组件的层级设置最高,那么按钮就不可点击,若是不设置最高,那么就不可拖拽了,有两种方式能够解决,一种是将按钮以插槽的方式放在组件中,另外一种是不将拖拽元素写成组件,之间将movable-area放在wxml的最外层,我采用的是第二种,若是每一个按钮都写成插槽的话维护起来太麻烦了小程序
/** * 数据缓存没有设置有效期 */ class Storage { /** * 获取缓存 * @param String $key key * @param String $def 若想要无缓存时,返回默认值则get('key','默认值')(支持字符串、json、数组、boolean等等) * @return value; */ get(key, def = '') { const timeout = parseInt(wx.getStorageSync(`${key}__separator__`) || 0); // 过时失效 if (timeout) { if (Date.now() > timeout) { this.remove(key); return; } } let value = wx.getStorageSync(key); return value ? value : def; } /** * 设置缓存 * @param String $key key * @param String $value value(支持字符串、json、数组、boolean等等) * @param Number $timeout 过时时间(单位:分钟)不设置时间即为永久保存 * @return value; */ put(key, value, timeout = 0) { let _timeout = parseInt(timeout); wx.setStorageSync(key, value); if (_timeout) { wx.setStorageSync(`${key}__separator__`, Date.now() + 1000 * 60 * _timeout); } else { wx.removeStorageSync(`${key}__separator__`); } return value; } remove(key) { wx.removeStorageSync(key); wx.removeStorageSync(`${key}__separator__`); return undefined; } } export { Storage }
场景:在跳转另外一个小程序以前须要调用接口获取跳转所需参数,在另外一个小程序返回时须要从新调用接口或许参数。
问题:首先想到的是点击跳转的时候调用接口,以后wx.navigateToMiniProgram跳转,将接口返回数据携带上,可是,这种不是用户直接触发的跳转,微信不支持。。。
而后,那就先在页面的onload事件中直接调用一次,而后再监听另外一个小程序返回,再调用一次接口,文档上写的很明白,监听App.onShow就行了,因而我在该页面的onshow直接wx.onAppShow监听场景值为1038,可是!!!这里遇到了巨坑,第一次返回,wx.onAppShow调用一次,第二次返回,wx.onAppShow调用两次,第三次返回,wx.onAppShow调用三次,直接致使整个流程出问题了。。。
解决:思考了很久,决定不用wx.onAppShow监听场景值的办法,直接在该页面直接定义一个变量,好比navigateToOther,默认为false,跳转成功后置为true,而后在onshow里判断是否为true,若是为true,调用接口,将navigateToOther置为false。完美解决!!!微信小程序
H5页面中的分享转发按钮不能直接分享给好友,只能用折中的方式来作,点击H5页面的分享按钮时,弹出提示框,指向右上角的转发按钮,并经过wx.miniProgram.postMessage将所需信息发送给小程序,用户点击转发按钮时能够经过bindmessage接收到消息
参考连接:小程序内嵌web-view之分享(2)数组
小程序嵌套H5页面时,有时页面在来回切换时须要刷新该H5页面,可是微信未提供相关接口,可是能够经过折中的方式来实现。缓存
首先,让webview作条件渲染:微信
<web-view wx:if="{{url}}" src="{{url}}" />
data: { base_url: config.kalatong_base_url + '……', url: '' }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { let url = this.data.base_url + "#wechat_redirect" this.data.url = decodeURIComponent(url) }, /** * 生命周期函数--监听页面显示 */ onShow: function() { this.refreshWebview() },
须要刷新时,先把url设为空,销毁当前webview。而后再把url设为当前值。以下:app
refreshWebview: function () { let tmpUrl = this.data.url; this.setData({ url: '' }); setTimeout(() => { this.setData({ url: tmpUrl }) }, 500); }
这样即可以在不影响导航栏历史的状况下刷新页面,也能够是跳转url。这里setData以后,页面内容的更新应该是异步执行的,所以咱们后一次修改url须要延时一小段时间,不然会出现error。猜想setData后页面实际更新应该是在下一次的requestAnimationFrame,所以若是页面彻底不卡顿可能16ms就能够了,保险起见,我设了100ms。可是100ms也不保险,有些页面会空白,最后置成500ms