血淚總結:如何從微信小程序的坑跳進支付寶小程序的大坑

衆所周知,iOS沒人要了,小程序如今火了...css

哈哈,開玩笑,不太小程序真是很是火

因此,今天我就來說講最近折騰出的小程序總結:如何從微信小程序的坑跳進支付寶小程序的大坑!vue

小程序很是適合不常用的線下服務場合,好比偶爾在某飯店點個菜,偶爾在某景區租個車,等等android

若是你已經有了微信小程序,那麼再開發一個支付寶小程序也並無多難.畢竟80%以上的代碼是通用的.最大的困難可能仍是對小程序語法/api的不熟悉,還有文檔不夠全面.web

因而我最近就經歷了這樣一系列填坑操做.json

小程序API差別:

xml

對於xml來講,最大的不一樣除了文件後綴名不一樣外,其實就是wx:改成了a:,還有事件綁定由bind開頭改成用on開頭:小程序

微信 支付寶 備註
文件名.wxml 文件名.axml 後綴名不一樣
wx:if a:if
wx:elif a:elif
wx:else a:else
wx:for-item a:for-item
wx:key a:key
bindtap onTap
bindsubmit onSubmit form組件
bindreset onReset form組件
bindinput onIpput input組件
bindchange onChange switch組件
bindmarkertap onMarkerTap map組件
bindcontroltap onControlTap map組件

css

css中二者幾乎如出一轍,基本不用改動,主要問題在map組件微信小程序

微信 支付寶 備註
文件名.wxss 文件名.acss 後綴名不一樣
90% 90vh!important map組件
// 地圖高度設置不能用標籤選擇器:#map
map {
  height: 90vh!important;
}
複製代碼

用其它方法來設置map組件的高度是不起做用的,必須加上!important;api

  • 若是還不起做用,請務必使用90vh!important這樣;數組

  • 若是還不起做用,請注意不要使用標籤選擇器:#mapbash

  • 若是還有問題,請在xml中調整一下,在全部組件最外層包上一個<view>組件,並將其設置爲100%寬高;

  • 別問我怎麼知道的,我搞了好幾天....

還有一點須要注意,相信你們也很容易看出來:
支付寶中view組件佈局默認是包裹內部組件;

也就是說若是view組件內部一個button,button寬高爲40rpx,那麼view不會全屏顯示,須要手動設置view組件width:100%;height:100%

js

js的文件後綴名是相同的,喜大普奔!
最大改變是將wx.改成了my.

微信 支付寶 備註
wx.showModal my.confirm
wx.getStorageSync('user') my.getStorageSync({ key: 'user' }).data 很是蛋疼!
wx.setStorageSync('area', res.data) my.setStorageSync({key: 'area', data:res.data}) 很是蛋疼!
wx.removeStorageSync('area') my.removeStorageSync({key:'area'}) 很是蛋疼!
wx.request my.httpRequest 注意參數header—>headers,結果中的res.statusCode-->res.status
wx.requestPayment my.tradePay 支付接口參數不一樣:支付寶爲拼接的參數,微信爲單獨參數;回調結果支付寶有三種狀態:成功,失敗,未知或支付中;微信只有成功,失敗
wx.getSetting 權限在對應api中獲取
wx.login my.getAuthCode 多了參數scopes: 'auth_user', // 主動受權(彈框):auth_user,靜默受權(不彈框):auth_base
wx.setNavigationBarTitle my.setNavigationBar 不只能設置title,還能設置背景色等
wx.createBLEConnection my.connectBLEDevice 藍牙
wx.closeBLEConnection my.disconnectBLEDevice 藍牙
wx.getSystemInfoSync().SDKVersion my.SDKVersion
wx.getSystemInfoSync().system my.getSystemInfoSync().platform 注意大小寫:系統平臺android/iOS—>系統平臺Android/iOS;另外個別安卓機型上可能爲空!!!!!
wx.createMapContext('map').includePoints({points: that.data.map.polyline[0].points}) that.data.map.includePoints = that.getPolyLine(data.border1).points 改成先在axml中綁定屬性,再設置
wx.openLocation() my.openLocation() 參數數量不一樣,類型不一樣

地圖組件中又出現了小麻煩,微信中是拿到mapContext直接設置包含的點,而支付寶中須要先在axml中綁定

<map include-points='{{map.includePoints}}'></map>
複製代碼

而後改變對應的值並that.setData賦值刷新界面.

還有打開內置地圖導航的API,也有差別:微信中只須要三個參數:經度,緯度,名稱.經緯度爲Number類型.而支付寶中須要四個參數:經度,緯度,名稱,地址.經緯度爲String類型

json

json的文件後綴名也是相同的,喜大普奔!

微信 支付寶 備註
navigationBarTitleText defaultTitle 標題
navigationBarBackgroundColor titleBarColor

更大的坑

藍牙適配器

更大的坑仍是出在了藍牙組件上,微信中屢次調用打開藍牙適配器沒有問題,但支付寶小程序中,藍牙已經鏈接的狀況下再重複調用就致使鏈接失敗或斷開重連:

wx.openBluetoothAdapter()—>my.openBluetoothAdapter()
複製代碼

因此建議先判斷適配器的狀態,在error回調中,根據err.code判斷髮現沒有打開時再打開藍牙適配器.

若是沒有提早打開Adapter,那麼後面的my.onBluetoothAdapterStateChange監聽是沒法工做的.

官方文檔:初始化小程序藍牙模塊,生效週期爲調用 my.openBluetoothAdapter 至調用 my.closeBluetoothAdapter 或小程序被銷燬爲止。 在小程序藍牙適配器模塊生效期間,開發者能夠正常調用下面的小程序API,並會收到藍牙模塊相關的 on 事件回調。

  1. my.getBluetoothAdapterState判斷是否已打開,已經打開可正常操做;
  2. 未打開的話,再調用my.openBluetoothAdapter來打開;
  3. 在complete回調中,再調用my.getBluetoothAdapterState判斷是否已打開,並設置監聽;

藍牙搜索新設備

接下來,是在搜索藍牙的回調裏,藍牙廣播中的advertisData格式不一樣,支付寶中是16進制的字符串,而微信中是ArrayBuffer,也就是二進制數組.

微信官方文檔也作了說明:advertisData爲當前藍牙設備的廣播數據段中的ManufacturerData數據段 (注意:vConsole 沒法打印出 ArrayBuffer 類型數據)

my.onBluetoothDeviceFound(function (res) {
    let devices = res.devices // 設備列表
    
    for (let i in devices) {
        //支付寶中,將16進制字符串轉換爲真正的字符串
        let mac = hexToString(devices[i].advertisData).toLowerCase()
        //微信中,將二進制數組轉換爲字符串
        //let mac = ab2str(devices[i].advertisData).toLowerCase()
        let deviceId = devices[i].deviceId
    }
}
複製代碼

獲取已鏈接的藍牙設備

還有一個不一樣,獲取處於已鏈接狀態的藍牙設備列表.

微信中只要傳入service數組就能夠準確獲取到對應的藍牙設備,並在success中給出設備的信息;

而支付寶中必須傳入廣播中公開的serviceId才能找到對應的設備,success回調中給出的也是設備的廣播數據...

舉個例子:一個藍牙設備:小米手環2s,共有4個service:['AAAA','BBBB','CCCC','DDDD'],其中AAAA和BBBB是公開的,也就是放在廣播中的,無須鏈接就能夠獲取到;而CCCC和DDDD是必須鏈接上以後才能獲取到的.

在微信中,傳入CCCC和DDDD,就能夠獲得當前已經鏈接中的'小米手環2s'(可能有多個,因此是數組);

而在支付寶中,傳入CCCC和DDDD獲得的是空數組.必須傳入AAAA或BBBB這種公開在廣播中的serviceId才能找到已鏈接的全部'小米手環2s':

my.getConnectedBluetoothDevices({   // 獲取處於已鏈接狀態的設備
    //services: [that.data.u1], that.data.u2],//支付寶中有限制
    success: function (res) {
        res.devices.forEach(function (ud, index) {
            if (ud.deviceId === that.data.deviceId) {//目標設備
                console.log('目標設備已鏈接',ud.deviceId,that.data.deviceId)
            }
        })
    } 
}

複製代碼

藍牙寫入操做

微信中寫入的value是ArrayBuffer即二進制,而支付寶中是Hex String即16進制字符串.

比較坑的是官方說明:

value: Hex String 必填 藍牙設備特徵值對應的值,16進制字符串,限制在20字節內

這個20字節,實際指的是二進制數據的長度,而16進制的2位才表明1字節,因此每次傳入的字符串長度應該是:小於40!!!!

my.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      value: value,
      success: function (res) {
        console.log('向藍牙寫入數據 success', res)
      },
      fail: function (res) {
        console.log('向藍牙寫入數據失敗', res)
        
      }
    })
複製代碼

藍牙狀態監聽

還有一個比較搞笑的是,支付寶小程序官方文檔中對藍牙各類監聽的說明:

// 開始監聽藍牙變化,先移除一下

my.offBluetoothAdapterStateChange();//tip: 爲防止屢次註冊事件監聽致使一次事件屢次回調,建議每次調用on方法監聽事件以前,先調用off方法,關閉以前的事件監聽。

my.onBluetoothAdapterStateChange(function (res) {/*監聽到適配器狀態改變*/})
複製代碼

全部的監聽事件api都加了說明,讓先調用off方法移除一下,以防重複監聽,這種操做讓我這個作過iOS原生藍牙開發的很是不適應,簡直啼笑皆非呀.

再看微信的小程序,根本就沒有off方法,估計是內部作了防止重複監聽的處理.

在安卓上打印爲空

4月份已經有人在官方論壇上反應onBluetoothDeviceFound返回值打印爲空了,官方迴應Demo是正常的.我也遇到了這個問題.

還有人說是打開調試開關致使的異常,但我關掉調試界面,也沒有用.....

通過與官方Demo的仔細對比,發現最大問題是裏面有數據,但在安卓上打印不出來...

my.onBluetoothDeviceFound(function (res) {
 let devices = res.devices // 設備列表
 console.log('onBluetoothDeviceFound', res)//打印出的res在安卓上爲空
 console.log(res)//打印出的res在安卓上爲[object Object]
 console.log(JSON.stringify(res))//在安卓上終於成功輸出了...
})
複製代碼

後來仔細一測試,安卓上,全部的東西都不能直接打印,官方示例中全都是用JSON.stringify(res)來打印輸出的.而正常取值是不受影響的.

蛋碎一地呀~!!!

switch-case的坑

在支付寶小程序中,一個簡單的switch-case語法居然出錯了!!!

switch (code) {
    case 0:
        console.log('0')
        break;
    case 1:
        console.log('1')
        break;
    case 2:
        console.log('2')
        break;
    default:
        console.log('default')
複製代碼

出錯緣由是,當code=0時,case 0分支沒法進入,直接進入了default分支,真是無比蛋疼!!!

其餘分支沒有問題,避免方法是,不使用case 0,改爲case 10~

安卓上刪除小程序不會清理數據

在微信上,若是用戶刪除了小程序,全部產生的/儲存的數據都會被清理掉。

在支付寶上,iOS 表現和微信一致,都會被刪除;而安卓上setStorageSync儲存的數據不會被刪除!!!!!

my.setStorageSync({ key: 'user', data: userData })
複製代碼

因此必須手動判斷刪除:

my.removeStorageSync({ key: 'user' })
複製代碼

真是讓人無比蛋疼!!坑爹啊!!!

地圖組件 control 控件的圖標

因爲如今支付寶地圖組件層級最高,尚未推出cover-image功能,因此要在地圖上覆蓋按鈕,就只能用control組件。這樣須要給control組件設置iconPath,以下:

controls: [{
    id: 10,
    iconPath: imgPath + "icon_new_user.png",
    position: {
      left: 280,
      top: 400,
      width: 35,
      height: 35
    },
    clickable: true
}]
複製代碼

這裏有個坑,就是position在安卓上正常的,在 iOS 上widthheight無效!!!!即永遠顯示圖片自身的真實大小!

更開放的 webview

微信中的 webview 組件有不少限制,最多見的是 webview 和小程序的通訊是受限的,雖然有專門的函數,可是官方說發送的數據只有在頁面銷燬或用戶手動點擊分享時,小程序纔會真正收到消息。

還有就是微信小程序中,webview 組件強制全屏且不可被覆蓋。

支付寶中就沒有這麼多限制。

總結

總之,支付寶小程序和微信小程序類似度很是高,熟悉js和vue的同窗能夠在2周內就熟練將一個小項目從微信小程序轉換成支付寶小程序;

二者的IDE也都是基於VS Code作的二次開發,界面相似,容易上手,目前支付寶小程序IDE的功能更少一些.

目前,二者坑很多,而支付寶小程序是比微信小程序更大的坑...

相關文章
相關標籤/搜索