最近在作公司的小程序項目時,須要作一個充值頁面,打算直接複用微信公衆號上已經開發好的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