最新更新时间:2019年11月01日13:42:34
《猛戳-查看我的博客地图-总有你意想不到的惊喜》
本文记录微信小程序开发过程中遇到的种种问题,归纳总结
概述
随着微信生态的不断发展,微信小程序的地位变的重要,几乎所有APP都会做小程序端的应用,虽然在开发过程中,开发成本比常规的网站类型的项目小,但也会遇到很多方案问题和技术瓶颈。
小程序原生页面和webview页面的双向通信
//webview页面的dom布局
<view class='container'>
<web-view wx:if="{{url}}" class='webview' src="{{url}}" bindload="bindload" binderror="binderror" bindmessage="bindmessage"></web-view>
</view>
//js 文件
data: {
url: ''
}
//webview 组件的三个原生事件
bindload(){
console.log('webview load success')
}
binderror(){
console.log('webview load error')
}
//网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data是多次 postMessage 的参数组成的数组
bindmessage(e){
console.log(e.detail.data)
}
- 小程序原生页面 跳转到 webview页面
//从A页面跳转到B页面,B页面是一个具有<web-view></web-view>组件的页面
let params = {a:1,b:2}
wx.navigateTo({
url: `/pages/webview/index?params=${JSON.stringify(params)}`,
})
//进入B页面后的装载webview数据,在B页面的onLoad生命周期方法中设置url
onLoad(options){
//使用从A页面传入的参数
let params = JSON.parse(options.params)
this.setData({
url: params.url
})
}
- webview页面 跳转到 小程序原生页面
//以react项目为例
componentDidMount(){
//获取url中路由参数
let query = this.props.history.location.search.slice(1)
}
//使用JSSDK向小程序原生页面跳转
enter(){
let params = {a:1,b:2}
wx.miniProgram.navigateTo({ url:`/pages/index/index?params=${JSON.stringify(params)}`})
}
//需要引入 JSSDK
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js" defer></script>
- webview页面 跳转到 小程序原生页面后,按左上角返回按键, webview页面刷新的问题
如果不在生命周期方法中做任何操作,此时回退到webview页面不会刷新,如果需要做刷新操作,有两种方案:
- 记录路由栈
- 不记录路由栈
//在<web-view></web-view>页面的onShow方法中做操作
//这种操作,web-view会记录自己的路由栈,每setData一次,路由栈会增加一级,此时在<web-view></web-view>页面按返回按钮,回退的是<web-view></web-view>自己的路由栈,而不是小程序自身的路由栈
onShow(){
this.setData({
url: params.url
})
}
//这种操作,web-view不会记录自己的路由栈,先清空url,wx:if="{{url}}"会销毁<web-view></web-view>组件,在回调中重新setData,相当于初始化<web-view></web-view>组件,<web-view></web-view>自身路由栈不会增加,此时在<web-view></web-view>页面按返回按钮,回退小程序自身的路由栈
onShow(){
this.setData({
url: ''
},()=>{
this.setData({
url: params.url
})
})
}
- 不记录路由栈的方案,部分机型存在bug
实测中,在iPhone X和iPhone XS等机型搭配的iOS 12.4.1系统下,webview的url先清空后赋值的方案中在binderror中报错如下:insertHTMLWebView:fail only one webView component
//webview页面的dom布局
<view class='container'>
<web-view wx:if="{{url}}" class='webview' src="{{url}}" bindload="bindload" binderror="binderror" bindmessage="bindmessage"></web-view>
</view>
//js 文件
data: {
url: ''
}
//webview 组件的原生事件
binderror(e){
console.log(e.detail.errMsg);//insertHTMLWebView:fail only one webView component
}
终极方案,解决从小程序原生页面回退到webview中,刷新webview并不记录webview自身路由栈的问题,方案如下:
//webview需要的url从公共数据app.globalData中读取,减少页面间通信的耦合度
onLoad(options){
this.setData({
url: app.globalData.url
})
}
//
onShow(){
if(this.firstEnter){
this.firstEnter = false;
return
}
wx.redirectTo({url:'index'})
}
//注意:这个方案会触发onUnload事件,如果之前有相关的逻辑,需要做兼容处理
onUnload() {
}
参考资料
- 无
感谢阅读,欢迎评论^-^