最近开发了一款微信小程序,在开发过程中遇到了一些微信小程序的坑,记录下来,希望对后边开发小程序的同学有点帮助。后期开发过程如果有新的踩坑记录,也会相应的更新在改文档中。
1、像素值与单位之间不能有空格
微信小程序的样式存放在.wxss文件,像素单位用rpx,官方文档有如下描述。
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
踩坑点:像素值和像素单位之间不能有空格,否则不起作用。即10rpx 能被识别;10 rpx则不能被识别;部分编辑器格式化之后会在数值和单位间有空格(webstorm即使如此)。
2、回调函数解决app.js 与 page之间因异步接口造成数据不同步问题
小程序在初始化时会执行app.js。通常微信登录小程序之后,根据具体的业务场景,需要判断小程序是否在业务中绑定。如果绑定则直接进入首页,如果没有绑定则进入绑定页面。
根据以上场景,我们需要在app.js中调用业务接口判断,是否存在绑定关系。代码大致如下: 通过调用wx.login()接口,获取返回的code值,然后将改code 传递给后端,查询微信与业务的绑定关系。
onLaunch: function (options) {
wx.login({
success: res => {
//获取微信返回的code
let code = res.code,
//调用业务接口
wx.request({
url: '微信是否绑定过业务',
data: {code, ... 其他参数},
method: 'POST',
success: res => {
/*因为接口是异步数据,可能Page.onLoad()方法先执行*/
let response = res.data
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(response)
} else {
commonUtil.initPage(response)
}
}
});
}
})
},
如果查询微信和业务有绑定,则应该会返回实际业务中的 token,且将token等相关信息存储在storage中,以便后续使用;如果没有绑定关系,则跳转到绑定关系的页面,其中initPage(),就是做此功能使用。
通常在我们在首页命名为index,在index页面中,一般有如下代码:根据微信登录的token值,查询具体的业务数据。
onShow: function (options) {
if (!util.getAppStoken()) {
app.userInfoReadyCallback = res => {
commonUtil.initPage(res);
}
} else {
this.queryRole();
}
},
然而存在一个问题,按照正常的小程序注册顺序,app中onLaunch先执行,然后再执行page中onShow(onLoad)方法。但是onLaunch方法中存在异步的接口,因此page中可能在接口返回数据之前就已经运行。此时page页面不一定能准确拿到onLaunch接口返回的token数据。
因此如上述代码所示,在page中,首先判断是否能拿到token,如果拿不到,给app实例添加回调函数,同时在onLaunch接口中判断是否存在该回调。如果能拿到token,则直接执行业务接口,根据token查询业务数据。
实际的运行过程 :
app:onLaunch — index:onShow — index:获取不到token — index:添加app 回调 — app:接口返回数据 —app:执行回调
(1)未绑定关系 — 绑定页面 — 绑定成功返回 token — 进去index — index:能获取token — 查询业务
(2)已绑定关系 — 返回 token — --- 进去index — index:能获取token — 查询业务
3、web-view内嵌H5,不能动态修改H5路径
微信小程序支持通过web-view方式内嵌H5,其中src属性指向网页的链接。如果该链接地址不是静态数据,而是从后端获取的。如果直接如下写法:
<web-view src="{{src}}"></web-view>
Page({
data:{
src:""
}
onLoad:function(){
......
this.setData({
src: '接口获取的src'
})
}
})
则会出现空白页面,查看此时data中的src数据,也确实更新到接口返回的数据。为什么跳转不进去正确的页面啦。
原因分析:小程序在解析时,遇到web-view标签时,就会立即跳转到对应的src属性的链接。此时小程序已经打开H5页面,但是小程序声明周期会继续执行,因此会出现AppData中数据发生改变,而H5中没有对应的参数。因此必须在初始化给出完整的链接地址(包含url参数)。
解决方法: 将web-view封装成组件,添加一个中间页面redirectH5,在这个中间页面中,onLoad方法中可以处理src,引用,并将src作为参数传入。代码如下:
<!--redirect-->
<web-view src="{{src}}"></web-view>
Component({
properties: {
src: {
type: String,
value: '',
observer: function (newval, oldval) {
}
},
}
})
<!--redirectH5-->
<redirect src="{{redirectUrl}}"></redirect>
Page({
data:{
src:""
}
onLoad:function(){
......
this.setData({
src: '接口获取的src'
})
}
})
原理解析:猜测原因是,页面的onLoad方法在组件的created方法之前执行。翻看官方文档,没有查看到相关的说明,如有那位同学看到了,可以分享给我。
4、web-view会覆盖其他组件
在微信小程序嵌入H5过程中,需要对H5的链接进行控制,防止外网或者非法域名的链接。因此最初设想在redirectH5中如下编码。
<view>
<view wx:if="{{isIllegalUrl}}" class="illegal-url">
<view class="illegal-text">域名配置不合法,请联系运营人员</view>
<view bindtap="goIndex" >
<button class="back-index">返回首页</button>
</view>
</view>
<redirect src="{{redirectUrl}}" wx:else></redirect>
</view>
当传入非法域名的时候,确实如设想一样,出现返回首页的按钮,但是发现按钮点击无效。初步怀疑是组件中web-view作祟。官方稳定如下解释:
每个页面只能有一个,会自动铺满整个页面,并覆盖其他组件
5、开发过程中,可以设置不校验合法域名、业务域名
小程序接口调用必须是域名访问的,且必须在小程序的配置中心添加合法域名、业务域名等。给调试带来麻烦,但是微信小程序的开发工具里,可以设置不校验域名。在本地开发的时候,可以通过调用IP联调。
6、授权获取用户信息需要按钮触发
在之前的微信小程序版本中,通过wx.authorize({scope: “scope.userInfo”}),就会弹窗询问用户是否授权获取用户头像、昵称等基本信息。最新版本的微信小程序文档,已经更改:
无法弹出授权窗口
注意:wx.authorize({scope: “scope.userInfo”}),无法弹出授权窗口,请使用
为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败
如果需要获取用户信息,使用button组件的open-type='getUserInfo’提供的开放能力,此外还需要设置bindgetuserinfo对应的方法。具体实现如下
<button open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="onGotUserInfo">获取用户信息</button>
//用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致
onGotUserInfo: function(e) {
console.log(e.detail.errMsg)
console.log(e.detail.userInfo)
console.log(e.detail.rawData)
}
7、http支持不友好
在微信小程序中引用的图片、链接等如果http不能正常显示或者访问,可以尝试一下https。项目经验告诉我,微信对http支持并不友好。
持续更新中。。。。。。