衆所周知,iOS沒人要了,小程序如今火了...css
哈哈,開玩笑,不太小程序真是很是火因此,今天我就來說講最近折騰出的小程序總結:如何從微信小程序的坑跳進支付寶小程序的大坑!vue
小程序很是適合不常用的線下服務場合,好比偶爾在某飯店點個菜,偶爾在某景區租個車,等等android
若是你已經有了微信小程序,那麼再開發一個支付寶小程序也並無多難.畢竟80%以上的代碼是通用的.最大的困難可能仍是對小程序語法/api的不熟悉,還有文檔不夠全面.web
因而我最近就經歷了這樣一系列填坑操做.json
對於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中二者幾乎如出一轍,基本不用改動,主要問題在map組件微信小程序
微信 | 支付寶 | 備註 |
---|---|---|
文件名.wxss | 文件名.acss | 後綴名不一樣 |
90% | 90vh!important | map組件 |
// 地圖高度設置不能用標籤選擇器:#map
map {
height: 90vh!important;
}
複製代碼
用其它方法來設置map組件的高度是不起做用的,必須加上!important
;api
若是還不起做用,請務必使用90vh!important
這樣;數組
若是還不起做用,請注意不要使用標籤選擇器:#map
bash
若是還有問題,請在xml中調整一下,在全部組件最外層包上一個<view>
組件,並將其設置爲100%寬高;
別問我怎麼知道的,我搞了好幾天....
還有一點須要注意,相信你們也很容易看出來:
支付寶中view組件佈局默認是包裹內部組件;
也就是說若是view組件內部一個button,button寬高爲40rpx,那麼view不會全屏顯示,須要手動設置view組件width:100%;height:100%
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的文件後綴名也是相同的,喜大普奔!
微信 | 支付寶 | 備註 |
---|---|---|
navigationBarTitleText | defaultTitle | 標題 |
navigationBarBackgroundColor | titleBarColor |
更大的坑仍是出在了藍牙組件上,微信中屢次調用打開藍牙適配器沒有問題,但支付寶小程序中,藍牙已經鏈接的狀況下再重複調用就致使鏈接失敗或斷開重連:
wx.openBluetoothAdapter()—>my.openBluetoothAdapter()
複製代碼
因此建議先判斷適配器的狀態,在error回調中,根據err.code判斷髮現沒有打開時再打開藍牙適配器.
若是沒有提早打開Adapter,那麼後面的my.onBluetoothAdapterStateChange
監聽是沒法工做的.
官方文檔:初始化小程序藍牙模塊,生效週期爲調用 my.openBluetoothAdapter 至調用 my.closeBluetoothAdapter 或小程序被銷燬爲止。 在小程序藍牙適配器模塊生效期間,開發者能夠正常調用下面的小程序API,並會收到藍牙模塊相關的 on 事件回調。
my.getBluetoothAdapterState
判斷是否已打開,已經打開可正常操做;my.openBluetoothAdapter
來打開;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 (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' })
複製代碼
真是讓人無比蛋疼!!坑爹啊!!!
因爲如今支付寶地圖組件層級最高,尚未推出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 上width
和height
無效!!!!即永遠顯示圖片自身的真實大小!
微信中的 webview 組件有不少限制,最多見的是 webview 和小程序的通訊是受限的,雖然有專門的函數,可是官方說發送的數據只有在頁面銷燬或用戶手動點擊分享時,小程序纔會真正收到消息。
還有就是微信小程序中,webview 組件強制全屏且不可被覆蓋。
支付寶中就沒有這麼多限制。
總之,支付寶小程序和微信小程序類似度很是高,熟悉js和vue的同窗能夠在2周內就熟練將一個小項目從微信小程序轉換成支付寶小程序;
二者的IDE也都是基於VS Code作的二次開發,界面相似,容易上手,目前支付寶小程序IDE的功能更少一些.
目前,二者坑很多,而支付寶小程序是比微信小程序更大的坑...