一、前言
近期,開始了一段辛酸的還未開始就已經結束的“創業”(參見我的第二次創業,以夢為馬,莫負韶華)。大體上是開發了一款微信小程序,關於創業這件事情就不細說了,本文主要介紹一下開發小程序的過程中踩過的幾個坑。
二、注冊
開發一款功能全乎的小程序,在未動鍵盤開始碼代碼之前就要涉及到賬號注冊、微信認證、支付申請等等,這里面也有一些坑。
首先是必須要企業認證才能有微信支付功能,以個人名義申請不能進行支付。微信認證還算容易,只需要支付300元即可。支付申請的時候會讓你選擇需要申請的經營種類,此處如果與企業執照上相同會比較容易通過,我們的經營項目不太一致,剛開始寫的比較簡單被直接駁回,后面我寫了一段比較長的話詳細解釋了一下要做個什么、為什么申請此類型,估計審核的人被我感動了,於是順利通過。
三、HTTPS和備案
如果小程序需要和后台交互,那么交互時只能選擇域名的方式,且此域名必須經過ICP備案,並且只能采用HTTPS方式。
ICP備案比較麻煩,可以直接選擇購買阿里雲服務器,這應該是最方便的方式了吧。
HTTPS建議使用百度雲,可以申請到一年的免費證書,申請也比較容易。
四、開發
回歸到本行。其實小程序開發是個涉及到方方面面的工作,要求還是蠻高的,一套下來基本也就是個全棧工程師了。
小程序本身就分前台和后台,就類似與網站開發,wxml對應html、wxss對應css、js就是js、還多了個json用於配置等。說白了就是微信把這些東西以一定的方式封裝起來了,但是我個人感覺封裝的也不是那么理想,所以有點不太順手。
小程序通信的后台可以采用各種語言,相當於網頁的后台,也基本等同於restful接口。此項目我們使用了python的django框架,開發起來還蠻容易的。
整個一套下來,哪方面都有接觸,我的合伙人包亮是個編程大牛,對我進行了很多指導,我對開發這件事情和js、python這兩種語言都有了全新的認識。
言歸正傳,下面開始介紹開發過程中踩過的坑。
4.1 js回調
剛開始js代碼寫的很冗長,一個函數有上百行。並不是我不懂得代碼編寫的藝術,而是小程序的js開發往往是一個請求中的sucess以及fail中嵌套另一個請求,函數只能越寫越長,最后各種功能交織在一起,變量也混雜在儀器,我自己實在看不下去了,於是開始重構,將一些功能提取出來組成函數,整體代碼清爽了不少,但是出現了一些讓我很費解的bug,大神簡單看了一下直接指出問題來了,本來應該嵌套的異步函數寫成了並列,這樣導致函數在執行的時候沒有時間上的先后順序,於是就會出現莫名其妙的bug,這個問題我是有所注意的,但是有些地方也確實沒有注意到,他告訴我你應該將各種回掉函數作為參數傳入,這樣就不會再出問題。簡單如下:
function b() {
// do something when sucess
}
function a() {
wx.request({
url:'...',
sucess: function(res) {
b();
}
})
}
a();
這是我原來寫的方式,當然比這復雜的多,所以不注意的時候就會將b寫到a的后面,其實真正的方式應該是這樣:
function b() {
// do something when sucess
}
function a(aSucess) {
wx.request({
url:'...',
sucess: function(res) {
aSucess()
}
})
}
a(b);
這樣就很清晰的知道a函數里當請求成功的時候做了什么事情,因為直接在調用a的時候就已經傳入其中了。
4.2 app.js中的異步函數如何保證可靠性
有的時候需要在app.js的onLaunch事件中向后台請求一些數據,比如用戶信息等等(非微信用戶信息,但需要與微信openid關聯),取出這些信息后在加載用戶頁面的時候會再向后台請求些數據進行展示等,但是app.js和頁面之間無法進行普通回掉,這樣就會造成在app.js中還沒有請求完成,數據還是undefined而頁面中使用此數據就會造成錯誤。后來查看了一些文檔,發現可以在app.js中為特定數據自定義事件,用於在其他頁面判斷,方式如下:
app.js中:
wx.request({
url: '',
success: res_user_info => {
if (this.userIdCallback) {
this.userIdCallback(res_user_info)
}
this.globalData.userId = res_user_info.data.id;
}
})
這樣就在app.js中定義了一個userIdCallback事件,該事件完成的時候表示已經從后台取到了用戶數據。在其他頁面即可通過此種方式進行判斷:
if (app.globalData.userId == null || app.globalData.userId == undefined) {
app.userIdCallback = res_user_id => {
// do something
}
} else {
// do something
}
即首先判斷此數據是否已經請求到,如果還未完成則等待此數據完成,然后在其回調函數中再完成有關操作。
4.3 tabBar之間的切換
如果在app.js中設置了tabBar,則頁面底部會出現相應的導航欄,但是頁面中使用wx.navigateTo跳轉到的頁面底部不顯示導航欄,並且如果需要切換到導航欄內的任何頁面,都需要使用wx.switchTab函數而不是wx.navigateTo函數。
4.4 數據綁定
微信小程序沒有數據雙向綁定,在Page對象中設置的data只能單向改變前台渲染,而前台改變無法同步更改此變量。那么如果需要將前台的變化也同步到后台,只能監控前台控件的變化事件,如input的bindinput事件,在此事件中對輸入值進行判斷,如下:
<input bindinput="bindMoney" value="{{money}}" />
其中value="{{money}}"用於后台到前台的綁定,而bindinput則用於前台到后台的綁定,如下:
bindMoney: function (e) {
var value = parseInt(e.detail.value);
this.setData({
money: value
})
}
並且小程序在綁定變化的時候前台會出現undefined的情況,如果是圖像的話就會造成請求錯誤,倒是無傷大雅,時間很短,前台基本不會察覺。
五、提交審核
這是最坑的一點,吭哧吭哧的做了半天,最后居然因為種種非技術原因而無法通過審核。好吧,最為個體我們真的無法說什么,只能對微信這個大平台言聽計從,希望我們更改相應頁面后能夠通過審核。審核太嚴失去了自由的土壤,微信如何保證有好的產品出現呢?
六、總結
本文簡單介紹了在微信小程序開發過程中踩過的一系列坑,希望對后來者能夠有所幫助。