微信小程序开发中遇到的坑和解决办法
1、原生组件的层级问题
video、canvas、camera等原生组件层级最高,其他组件无论z-index为多少,都无法覆盖在原生组件上。
这里拿video组件做示例,如果需要点击视频支持微信开放能力,例如授权手机号,获取用户信息等,必须要利用button组件,如果在原生组件外层添加button组件,点击视频并不会触发button事件,代码如下,这里点击视频并不会弹出授权手机提示,触发getPhoneInfo函数。
<button open-type='getPhoneNumber' bindgetphonenumber='getPhoneInfo'>
<video src="{{videoUrl}}"></video>
</button>解决办法:利用 cover-view 组件,原生组件只支持嵌套cover-view和cover-image组件,且cover-view内可以使用button。
代码如下,同时用css隐藏button,并全覆盖video即可实现点击视频弹出授权手机提示,此时点击控制栏无效。这里视频是自动播放不可控,如果需要控制视频或者是自定义播放按钮图标等,可以在button内嵌套cover-image自定义即可。
<video src="{{videoUrl}}" autoplay controls="{{false}}">
<cover-view>
<button open-type='getPhoneNumber' bindgetphonenumber='getPhoneInfo'>
<cover-image src="{{imgUrl}}" />
</button>
</cover-view>
</video>tips:video的层级问题在开发者工具中不会显露出来,z-index会起作用,一定要在真机上测试。
2、ios和android部分组件表现的差异
ios
video:微信最小化后正在播放的video会暂停,需要再次点击播放按钮,如果视频设置的是不可控,没有开始播放按钮,视频暂停了就无法继续播放了,android没有该问题。
<video id="video" src="{{videoUrl}}" loop autoplay controls="{{false}}">
</video>解决办法:创建video上下文VideoContext 对象,页面每次onShow的时候执行相应操作。
onReady: function () {
this.videoContext = wx.createVideoContext('video')
},
onShow: function () {
if (this.videoContext) {
this.videoContext.play()
}
},android
input:限制了输入的最大长度,达到最大长度后再次输入是没有显示的,但是input的value值包含最大长度后面的输入。
<input bindinput='phoneChange' maxlength="4" type="number" />
phoneChange: function(e){
console.log('e.detail.value)
//小键盘输入12345,实际获取到的ios的值为1234,android是12345,input组件显示的是1234
}3、登录之后的session_key失效
冷启动进入小程序,app.js在onLaunch调用登录接口,通过登录code,后端拿到session_key之后,后续可解密encryptedData(getPhoneNumber,getUserInfo),校验用户信息signature(getUserInfo),如果后续用户一直是热启动进入小程序,不会在onLaunch中重新登录,同时用户没有在小程序有过操作从而延长session_key的有效期,后续操作就会出现session_key失效,报错。
解决办法:在onShow中调用登录接口,同时为了避免没必要的调用,可通过wx.checkSession( )检查登录状态是否过期,如果过期就重新登录,代码如下。
onShow: function () {
wx.checkSession({
success: () => {
wx.login({
success: res => {
if (res.code)
wx.request({ // 换取openid,session_key等信息
url: 'https://test.com/onLogin',
data: {
code: res.code
},
})
}
},
})
},
})
},4、预览文档问题
两种方法
1 web-view组件
在微信后台设置好域名后直接调用
<web-view src="{{url}}"></web-view>如图所示:

但是android会下载该文件,这并不是用户想看到的,也可以考虑用以下方法。
2 wx.openDocument( )
wx.downloadFile({
url: 'http://example.com/somefile.pdf',
success: function(res) {
const filePath = res.tempFilePath
wx.openDocument({
filePath: filePath,
success: function(res) {
console.log('打开文档成功')
}
})
}
})效果图如下:

对比两个方法的效果图,可以看到方法2是跳出了小程序的,无法使用小程序提供的功能菜单了。