最新更新時間: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() {
}
參考資料
- 無
感謝閱讀,歡迎評論^-^