微信小程序開發(fā)入門

寫在前面

微信小程序出來也蠻久了,經(jīng)過了市場的考驗,已經(jīng)站穩(wěn)腳跟,融入到了各行各業(yè),市場需求激增打來的是開發(fā)人員的緊俏,現(xiàn)在已經(jīng)各大招聘網(wǎng)站也能看到有小程序開發(fā)的崗位在提供。恰逢公司有業(yè)務(wù)需要,現(xiàn)在入坑小程序開發(fā),以一個初學(xué)者的身份把這一過程進行記錄并分享,希望能在和朋友們的交流中提升自我。

其實但凡有一丟丟的編程基礎(chǔ),想入門都是很簡單的事情,只要能跟著 官方文檔 把流程走一遍,就算入門了。現(xiàn)在不比早期,官方文檔被吐槽寫的跟 shi 一樣,所以還==非常推薦大家仔細讀一下官方文檔==。經(jīng)常在交流的時候,看到有人連官方文檔上寫的清清楚楚的東西都拿來問,這是很可悲的事情。

有些問題官方文檔上查不到,可以在官方 開發(fā)者社區(qū) 上輸入關(guān)鍵字查一下,基本上前期遇到的問題都能得到解決。這兩個地方都不能解決困惑的話,再去交流群求問或查看第三方論壇,如 很快-微信開發(fā)平臺 。甚至說有的同學(xué)喜歡看視頻,網(wǎng)上也能找到。當(dāng)然也建議大家?guī)е鴮嵺`結(jié)論和個人理解去交流,這樣容易得到答案,個人成長也會很快。

一、開發(fā)準備

不同于以往的項目,開發(fā)人員寫完代碼就可以了,在小程序開發(fā),尤其是個人項目中,開發(fā)人員需要兼顧開發(fā)、運維、推廣、客服等多個任務(wù),雖然這一切都有微信提供的管理后臺,但還是需要開發(fā)人員進行相關(guān)配置來保障項目的運行。

1. 小程序注冊

可以把小程序理解為在微信大市場上注冊的小商家,那么每個小程序就需要在 微信公眾平臺 注冊賬號用于管理。這個賬號可以提供給我們小程序的唯一標示 AppId ,也可以幫助我們對小程序進行管理,協(xié)助我們完成編碼開發(fā)以外的事情。注冊方式主要兩種:

1.1 官網(wǎng)注冊

立即注冊 -> 小程序

1.2 已有公眾號后臺(不支持個人類型公眾號)

小程序 -> 小程序管理 -> 快速注冊并認證小程序

補充:

- 注冊賬號要注意賬號類型,選擇小程序

- 小程序暫不支持更換主體(個人/企業(yè)),注冊時類型不要選錯

? ? - 個人類型小程序不支持不部分權(quán)限:如,微信用戶手機號、微信支付、微信卡券等

- 同一郵箱不能注冊多個公眾平臺賬號,同一微信賬號可以登錄多個公眾平臺賬號

? ? - 多人管理開發(fā),均使用同一賬號登錄,微信掃碼確認登錄;其他人(非管理員)的微信賬號可以通過配置 用戶身份-登錄權(quán)限 來擁有該能力

- 企業(yè)需要進行主體信息認證,周期較長,有 300 塊費用,通過了還不能更改,所以要慎重填寫

- 綁定開發(fā)者,并給與不同的權(quán)限

2. 開發(fā)工具

下載地址

基本使用簡單,畢竟中文版,下載了看著引導(dǎo)創(chuàng)建一個 QuickStart? 新項目,就能開擼了。或者下載這個 演示源碼,當(dāng)項目跑一下。整個開發(fā)工具還是挺清爽的,有種小霸王 N 合一的感覺。其中模擬器、編輯器、調(diào)試器都很直觀,可以通過左上角按鈕進行顯隱操作,使用上搞過前端開發(fā)的都比較熟悉,此處不再贅述。說一下幾個常用功能鍵:

2.1 預(yù)覽、遠程調(diào)試

兩種真機調(diào)試的方案,各有不同的適用場景和注意事項:

- 預(yù)覽

? ? - 需要擁有開發(fā)者權(quán)限的微信賬號掃描才能使用,常用于他人在未發(fā)版情況下體驗最新代碼

? ? - 只有IDE登錄微信賬號掃描時,才和IDE共用一套緩存(此時IDE清緩存可以影響到真機)

? ? - 可以開啟調(diào)試模式(微信右上角菜單 -> 打開調(diào)試),通過 vConsole 按鈕展示真機調(diào)試區(qū)

? ? - 看不到請求具體信息,只能通過控制臺打印

- 遠程調(diào)試

? ? - 可以在PC上看到真機的控制窗口,常用于配合測試人員復(fù)現(xiàn)問題

? ? - 獨立于IDE緩存,即賬號A登錄成功遠程調(diào)試后,賬號B進入遠程調(diào)試,看到的是賬號A的信息

? ? - 此時清緩存不能使用IDE清緩存,只能在遠程調(diào)試窗口執(zhí)行 wx.clearStore() 這種方式

? ? - 也沒有 network

2.2 清緩存

開發(fā)和測試中需要經(jīng)常模擬登錄、授權(quán)的不同處理結(jié)果,此時就需要用到清緩存功能。IDE 提供了以下功能,可以一次全清也可以清除某一項,對應(yīng)真機調(diào)試的實現(xiàn)如下:

- 清除代碼緩存

? ? - 相當(dāng)于真機調(diào)試時 - 刪除小程序重新加載代碼

- 清除授權(quán)緩存

? ? - 相當(dāng)于真機調(diào)試時 - 微信右上角菜單 -> 關(guān)于xxx -> 右上角菜單 -> 設(shè)置?

- 清除數(shù)據(jù)緩存

? ? - 相當(dāng)于真機調(diào)試時 - vConsole -> Wechat -> 點擊wx.clearStorage()

- 清除網(wǎng)絡(luò)緩存

? ? - 真機調(diào)試的網(wǎng)絡(luò)緩存暫不清楚如何清除,靜態(tài)資源通過增加時間戳

? ? ? ? - 注意同一個時間戳對應(yīng)同一份資源緩存

? ? ? ? - Date.parse(new Date()).toString().slice(0, 8) 固定間隔 100s

? ? ? ? - Date.parse(new Date()) / (space * 60 * 1000)? 根據(jù) space 設(shè)置間隔分

- 清除登錄緩存

? ? - 由于是靜默登錄,一般忽視該緩存

2.3 上傳

開發(fā)完成后,小程序發(fā)布前,需要將代碼上傳到微信的服務(wù)器。關(guān)于上傳有以下需要注意:

- 每個擁有開發(fā)權(quán)限的賬號都可以上傳,每個賬號上傳的代碼是分開的

- 每個人只能保持一份上傳的代碼,二次上傳會進行覆蓋

- 微信公眾平臺 / 開發(fā)管理

? ? - 線上版本

? ? - 審核版本

? ? ? ? - 展示審核中和審核通過但未發(fā)布的版本

? ? ? ? - 同時只有一個版本進行展示

? ? ? ? - 首次審核周期較長,需要3-5個工作日,此后審核較快

? ? ? ? - 首次審核較為嚴格,需要注意很多問題,如誘導(dǎo)分享,詳見[常見拒絕情形](https://developers.weixin.qq.com/miniprogram/product/reject.html#36-UI-%E8%A7%84%E8%8C%83)

? ? - 開發(fā)版本

? ? ? ? - 每個版本都可以設(shè)為體驗版本,但同時只有一個體驗版本,通過二維碼供擁有體驗者權(quán)限的人進行測試

? ? ? ? - 每個版本都可以提交審核,但同時只有一個審核中版本

? ? ? ? - 每個賬號維護一份開發(fā)版本

2.4 詳情(IDE右上角)

- 項目設(shè)置

? ? - 可以選擇調(diào)試基礎(chǔ)庫,來測試兼容問題(存在兼容問題的 api 都寫了最低版本,也可以查看 [歷史更新日志](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/uplog.html) 進行了解)

? ? - 未設(shè)置合法域名時,可以勾選 不校驗安全域名 選項(線上域名一定要 TLS/SSL 認證)

- 域名信息

? ? - 查看合法域名

二、開發(fā)優(yōu)化

1. promisify

https://github.com/stefanpenner/es6-promise

由于小程序提供的 API 都是回調(diào)風(fēng)格的,在習(xí)慣了 ES6 promise 風(fēng)格后,對回調(diào)嵌套不是很感冒,所以考慮進行包裝處理。此處小程序提供的 Promise 有兼容問題,所以使用了 es6-promise 包來進行包裝。

```

/**

* 將小程序的API封裝成支持Promise的API

* @params fn {Function} 小程序原始API,如wx.login

*/

function wxPromisify(fn) {

? return (obj = {}, cb) => {

? ? return new Promise((resolve, reject) => {

? ? ? obj.success = (res) => {

? ? ? ? resolve(res);

? ? ? };

? ? ? obj.fail = (res) => {

? ? ? ? reject(res);

? ? ? };

? ? ? let taskObj = fn(obj);

? ? ? cb && (typeof cb == 'function') && cb(taskObj);

? ? })

? }

}

```

討論:如何拿到原生 api 的返回值?

promise 給了我們在 success 回調(diào)中使用 return 關(guān)鍵字的能力,但沒有 api 執(zhí)行后的 return 失去了。此處使用 callback 拋出返回值,但是感覺并不優(yōu)雅,有更好處理方式的請指點下我。

2. request

小程序提供的原生接口是 wx.request ,出于以下幾點考慮,對其進行二次封裝:

1. 小程序沒有 cookie ,需要在 heaser 中攜帶 sessionId

2. 原生寫法是回調(diào)風(fēng)格,改造成 promise 風(fēng)格

3. 需要公用部分業(yè)務(wù)相關(guān)的數(shù)據(jù)處理

4. 需要對請求進行統(tǒng)一攔截處理,如 loading 、timeout

3. 按鈕節(jié)流閥

經(jīng)常這種需求,按鈕不能連續(xù)點擊,所以提供一個節(jié)流功能的工具:

<pre>

function btnThrottle(self){

? selt.setData({

? ? buttonClicked: true?

? });

? setTimeout(() => {

? ? self.setData({

? ? ? buttonClicked: false

? ? })

? }, 500)

}

creat: function() {

? if(this.data.buttonClicked) return;

? util.btnThrottle(this);

}

</pre>

4. 代碼清緩存

有時候在調(diào)試的時候需要經(jīng)常保持代碼最新,經(jīng)常執(zhí)行刪除小程序還是很麻煩的,可以考慮使用下面方法:

```

onHide: function() {

? wx.setEnableDebug({

? ? enableDebug: true,

? ? success: () => {

? ? ? wx.setEnableDebug({

? ? ? ? enableDebug: false

? ? ? })

? ? }

? })

}

```

- 優(yōu)點:可以清除代碼緩存,每次打開都是重新加載

- 缺點:沒辦法保持退出時的狀態(tài),所以暫不考慮用到生產(chǎn)環(huán)境

三、常見問題

1. 登錄邏輯

官方建議自己保存用戶登錄狀態(tài),不要頻繁調(diào)用 wx.login ,否則會被限制登錄。

有兩種思路:

1. 先檢查登錄是否過期(wx.checSsession),在未過期的基礎(chǔ)上執(zhí)行其他請求(不是所有請求都需要登錄,如世界排行)

2. 所有 api 請求都執(zhí)行判斷,如果返回未登錄錯誤碼(getUserInfo:fail auth deny),則申請授權(quán)(wx.authorize),授權(quán)成功繼續(xù)請求,授權(quán)拒絕則強跳授權(quán)頁(wx.openSetting)

目前登錄判斷:

1. wx.checkSession、wx.getStorage 檢查登錄是否過期和 sessionId 是否存在

2. 成功則判斷結(jié)束,否則 wx.login、wx.getUserInfo 拿到用戶信息

3. 成功則用拿到的信息向后臺登錄生成 sessionId,失敗則申請授權(quán)操作(允許授權(quán)會繼續(xù),失敗授權(quán)強跳授權(quán)頁)

4. 成功拿到 sessionId 則保存 storage,失敗提示網(wǎng)絡(luò)問題

[最優(yōu)體驗:](https://mp.weixin.qq.com/s/JBdC-G9MwaptFjQeD9ujeA)

1. 調(diào)用 wx.login 獲取 code,然后從微信后端換取到 session_key,用于解密 getUserInfo返回的敏感數(shù)據(jù)。

2. 使用 wx.getSetting 獲取用戶的授權(quán)情況

? ? - 如果用戶已經(jīng)授權(quán),直接調(diào)用 API wx.getUserInfo 獲取用戶最新的信息;

? ? - 用戶未授權(quán),在界面中顯示一個按鈕提示用戶登入,當(dāng)用戶點擊并授權(quán)后就獲取到用戶的最新信息。

3. 獲取到用戶數(shù)據(jù)后可以進行展示或者發(fā)送給自己的后端

2. 路由跳轉(zhuǎn)相關(guān)

系統(tǒng) api 和 navigator 組件支持新開、重定向、返回、tab切換、重啟動五種方式。讀懂路由出入棧規(guī)則,可以幫你較好的處理跳轉(zhuǎn)問題。但歸根結(jié)底我們還是應(yīng)該避免過于復(fù)雜的跳轉(zhuǎn)邏輯,防止分享進入時的路由跳轉(zhuǎn)問題。

有一種情況需要格外注意,在實現(xiàn)后退功能的時候,可能已經(jīng)沒有辦法后退了(如分享卡片進入或已經(jīng)退出當(dāng)前頁面但代碼還在執(zhí)行),此時執(zhí)行 wx.navigateBack 會閃退。

```

// 兼容處理不同打開方式的后退

function toHome() {

? let pageCount = getCurrentPages().length;

? if(pageCount > 1) {

? ? wx.navigateBack({

? ? ? delta: 1

? ? })

? } else {

? ? wx.redirectTo({

? ? ? url: '/pages/home/index'

? ? })

? }

}

```

需要注意的是 tab 切換時的路由出入棧規(guī)則:

- tab a 到 tab b 相互切換時,觸發(fā)的是 onHide 和 onShow(第一次切換會有 onLoad)

- tab a 的子頁面切到 tab b 時,會把所有 a 的子頁面 onUnload

3. 數(shù)據(jù)共享的實現(xiàn)

1. url傳值 - 基于頁面 - 適合少量值傳遞

```

wx.navigateTo({

? url: '/page/home/index?id=' + id

})

onload: function(opt) {

? console.log(opt.query)

}

```

2. storage - 基于本地緩存 - 適合大量值傳遞

注:

- 同一個微信用戶,同一個小程序 storage 上限為 10MB

- localStorage 以用戶維度隔離,同一臺設(shè)備上,A 用戶無法讀取到 B 用戶的數(shù)據(jù)

- 不建議將關(guān)鍵信息全部存在 localStorage,以防用戶換設(shè)備的情況

[官方文檔-api-數(shù)據(jù)緩存](https://mp.weixin.qq.com/debug/wxadoc/dev/api/data.html)

3. 全局 App - 基于內(nèi)存

```

getApp().globalData.xxx

```

4. 退出當(dāng)前頁面后,代碼還在執(zhí)行

由于用戶退出頁面的操作具有不可控性,所以隨時都可能出現(xiàn)代碼不在當(dāng)前頁面執(zhí)行的情況,而這種情況并不是我們想要看到的。所以需要對這種情況進行處理,保證代碼執(zhí)行穩(wěn)定可控。常見的有異步請求、定時器。所以最基本的要求就是在退出頁面是執(zhí)行以下操作:

```

onUnload: function () {

? ? // 中斷請求

? ? if (wx.canIUse('requestTask.abort')) {

? ? ? this.abortInit && this.abortInit.abort();

? ? }


? ? // 清理定時器

? ? clearInterval(this.xxxTimer);

? ? // 重置數(shù)據(jù)

? ? self.setData({

? ? ? ? //...

? ? });

? },

```

但總有漏網(wǎng)之魚,在開發(fā)中我就遇到過,請求中斷了,定時器清理了以后還在執(zhí)行的情況。出現(xiàn)這種情況第一感覺并沒有清理成功,API 執(zhí)行出現(xiàn)了問題。

后來測試多次發(fā)現(xiàn),并非 API 的鍋,而是因為在未能中斷的異步操作中觸發(fā)了新的異步操作,而新的異步操作已經(jīng)無法控制中斷。如:某個 request 請求沒能 abort 中斷,該操作的回調(diào)中又調(diào)起了另一個 request 或 setTimeout ,此時場面失控了。

所以,流程清晰可控是必須的,各位在處理業(yè)務(wù)邏輯的時候一定要注意此類問題的出現(xiàn)。

5. share

作為非常重要的一個推廣途徑,用戶分享自然是個很重要的功能點,小程序提供了相關(guān)的 API ,在使用中遇到以下問題并記錄:

1. 分享最終執(zhí)行的是 onShareAppMessage 對應(yīng)的函數(shù),相關(guān)的邏輯在其中處理

2. 分享的參數(shù) imageUrl 存在低版本兼容問題,設(shè)置為 null 不能實現(xiàn)默認截屏, '' 可以截屏

3. 分享可以攜帶參數(shù),寫在 path 參數(shù)中即可,同 url 中的 query

? ? - 如果需要獲取該參數(shù),可以在 onShow 的參數(shù) options 中獲取到

4. 場景需要:分享到群判斷,并判斷是否群分享進入

? ? - 先設(shè)置帶 shareTicket 的轉(zhuǎn)發(fā)

? ? ? ? ```

? ? ? ? wx.showShareMenu({

? ? ? ? ? ? withShareTicket: true

? ? ? ? });

? ? ? ? ```

? ? - 在分享的成功回調(diào)函數(shù)中判斷 shareTickets 群標識,存在即為分享到群

? ? - 獲取場景值(onShow 的參數(shù) options 中 scene),判斷進入方式,常用場景值:

? ? ? ? - 1007:單人對話小程序卡片

? ? ? ? - 1036:App 分享消息卡片

? ? ? ? - 1044:群分享小程序卡片

6. 自定義分析

產(chǎn)品的良性發(fā)展自然少不了運營進行數(shù)據(jù)分析,常規(guī)做法是進行埋點統(tǒng)計。而小程序已經(jīng)提供給用戶一套相對來說比較完善的數(shù)據(jù)分析功能,可以登錄微信公眾平臺 -> 數(shù)據(jù)分析查看,也可以通過小程序助手(官方小程序)便捷查看,當(dāng)前前提是需要賬號擁有數(shù)據(jù)分析的權(quán)限。

雖然官方提供的數(shù)據(jù)分析已經(jīng)滿足大部分需求,但是實際生產(chǎn)中肯定還需要定制數(shù)據(jù)分析,這里也有提供自定義分析。實現(xiàn)起來就是,先在微信公眾平臺進行自定義分析的事件注冊,如果選擇 API 上報則還是需要進行埋點配合。以下對自定義分析作簡要說明:

1. 最低版本

? - 自定義數(shù)據(jù)上報僅對微信6.5.4及以上版本生效,涉及時間為 2017-01-23 以后更新即可

2. 新建事件

? - 事件名稱

? ? - 英文名稱:用于 API 上報

? ? - 中文名稱:用戶管理后臺

? - 配置信息

? ? - 動作觸發(fā)

? ? ? - trigger

? ? ? ? - click

? ? ? ? - 生命周期

? ? ? ? - share

? ? ? ? - switchTab

? ? ? - action

? ? ? ? - 一次性

? ? ? ? - 分步驟

? ? ? - page

? ? ? ? - app 層面的不用設(shè)置,默認 ANY_PAGE

? ? ? - element

? ? ? ? - click 需要觸發(fā)元素,類或id選擇器

? ? ? - data

? ? ? ? - 收集數(shù)據(jù)源,有默認字段和自定義字段

? ? ? ? - 自定義字段

? ? ? ? ? - 默認是從 page 實例的 data 中獲取,字段名用于統(tǒng)計顯示,字段值是指 data 中的 key

? ? ? ? ? - 也可以選擇其他數(shù)據(jù),看文檔(渲染出來的list 、 wxml中的data-、 app實例的數(shù)據(jù)、系統(tǒng)屬性)

? ? - API上報

? ? ? - 字段信息可以不填

? ? ? - 可自動生成代碼

? ? - 二者的選擇

? ? ? - 根據(jù)實際情況來,有時候點擊滿足不了要求

3. 測試事件

? - 保存并測試

? - 連續(xù)測試有時候測不到數(shù)據(jù),不要擔(dān)心,退出公眾平臺賬號重新登錄再測

4. 發(fā)布事件

? - 保存并發(fā)布

7. 微信服務(wù)通知

場景需求:開發(fā)者希望主動發(fā)送信息給用戶

說明:該功能不建議頻繁發(fā)送信息,可能會被用戶主動拒收,而且該功能需要用戶本人在微信體系內(nèi)與頁面有交互行為后觸發(fā)(主動觸發(fā))

重點:獲取用戶的 formid

實現(xiàn):

1. 必須通過 form 組件提交才能獲取 formid

2. form 組件設(shè)置 report-submit='true'

3. form 組件添加 bindsubmit 事件, event.detail = {value: {'name': 'value'}, formId: ''}

4. 必須用戶手動觸發(fā)提交表單,不能 js 模擬提交,即必須有按鈕

8. 小程序互相跳轉(zhuǎn)

- 基礎(chǔ)庫 1.3.0 開始支持,低版本需做兼容處理

- iOS 微信客戶端 6.5.9 版本開始支持,Android 客戶端即將在 6.5.10 版本開始支持,請先使用 iOS 客戶端進行調(diào)試

注:需要關(guān)聯(lián)同一公眾號

寫在最后

以上內(nèi)容并不能幫助大家熟練完成小程序開發(fā),只是簡單入門、踩坑記錄、常見業(yè)務(wù)場景處理,還有非常多自己還沒踩到的東西,如自定義組件、插件、分包加載都還沒使用,API 也只用了有限的幾個,比較重要的 微信支付 也未使用,后面用到了再一一記錄。寫出來方便大家快速接入小程序,也是自己的學(xué)習(xí)總結(jié),有描述錯誤或不完善的地方,還請大家能夠和我聯(lián)系,相互學(xué)習(xí)交流。

問個問題:為啥我的代碼片段展示出來和別人的不一樣呢?```沒用錯啊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容