實(shí)體門店的一站式管理軟件
智慧門店系統(tǒng),線上線下一體化在 __appServiceEngine__ 對(duì)象中,對(duì) App 和 getApp 屬性的定義如下:
// 其中的 t 就是 __appServiceEngine__ 對(duì)象 var i = n(17); Object.defineProperty(t, "App", { enumerable: !0, get: function() { return i.appHolder } }), Object.defineProperty(t, "getApp", { enumerable: !0, get: function() { return i.getApp } }),
而這兩個(gè)屬性對(duì)應(yīng)的實(shí)現(xiàn)分別為 appHolder() 和 getApp() 方法,定義如下:
l = void 0, t.appHolder = (0, i.surroundByTryCatch)(function(e) { l = new y(e) }, "create app instance"), t.getApp = function() { return l },
由上可知,在 appHolder() 方法中,把外部傳入的 object 對(duì)象傳給 y(...) 方法進(jìn)行初始化一個(gè)小程序?qū)嵗龑?duì)象,并把結(jié)果賦給變量 l 緩存起來(lái),而在 getApp() 方法中則直接 return l,返回當(dāng)前小程序?qū)ο蟆?/p>
在上述 page-frame.html 中,我們知道,在 app.js 被加載完后,小程序框架會(huì)立即執(zhí)行 require('app.js') 進(jìn)行注冊(cè)小程序?qū)嵗磳?duì) App() 函數(shù)進(jìn)行調(diào)用(開(kāi)發(fā)者已經(jīng)在 app.js 中定義好了入?yún)?duì)象),如下:
<script src="./app.js"></script> <script>require("app.js")</script>
在 App() 函數(shù)中,最終會(huì)調(diào)用 y(...) 方法進(jìn)行初始化,其中 y(...) 的定義比較長(zhǎng),我們這里不再貼出代碼,詳情請(qǐng)自行查閱 WAService.js ,它的處理流程如下:
聲明 App.getCurrentPage 方法將被廢棄,請(qǐng)使用 getCurrentPages() 全局方法;
綁定生命周期函數(shù),即把外部入?yún)?duì)象定義的屬性綁定到小程序?qū)嵗龑?duì)象中,包括 onLaunch, onShow , onHide , onUnlaunch 和 onPageNotFound ;
綁定開(kāi)發(fā)者自定義的其他屬性(包括數(shù)據(jù)和方法),并校驗(yàn)屬性名是否為 “getCurrentPage”,如果是則警告;
根據(jù)外部是否有定義 onError 屬性判斷是否注冊(cè)錯(cuò)誤上報(bào);
檢查啟動(dòng)參數(shù)(取自__wxConfig.appLaunchInfo)并依次調(diào)用 onLaunch 和 onShow 方法;
注冊(cè)前后臺(tái)切換回調(diào) onShow 和 onHide ;
注冊(cè)找不到頁(yè)面的回調(diào) onPageNotFound ;
返回實(shí)例給 App() 函數(shù)進(jìn)行緩存。
根據(jù) 文檔 , Page() 函數(shù)用來(lái)注冊(cè)一個(gè)頁(yè)面,接收一個(gè) object 對(duì)象參數(shù),其指定頁(yè)面的初始數(shù)據(jù)、生命周期函數(shù)、事件處理函數(shù)等。 Page() 函數(shù)的聲明如下:
function Page(page: PageOptions): void
對(duì)于入?yún)?nbsp;object 對(duì)象(PageOptions)的屬性說(shuō)明如下:
此外, getCurrentPages() 函數(shù)用于獲取當(dāng)前頁(yè)面棧的實(shí)例,以數(shù)組形式按棧的順序給出,第一個(gè)元素為首頁(yè),最后一個(gè)元素為當(dāng)前頁(yè)面。它的聲明如下:
function getCurrentPages(): object[]
同樣地,在 __appServiceEngine__ 對(duì)象中,對(duì) Page 和 getCurrentPages 屬性的定義如下:
var r = n(2); Object.defineProperty(t, "Page", { enumerable: !0, get: function() { return r.pageHolder } }), Object.defineProperty(t, "getCurrentPages", { enumerable: !0, get: function() { return r.getCurrentPages } }),
而這兩個(gè)屬性對(duì)應(yīng)的實(shí)現(xiàn)分別為 pageHolder() 和 getCurrentPages() 方法,定義如下:
var k = void 0, // 保存當(dāng)前顯示的頁(yè)面(棧頂) x = [], // 保存已加載過(guò)的頁(yè)面歷史棧數(shù)組 // 其中的 t 就是 __appServiceEngine__ 對(duì)象 t.getCurrentPage = function() { return k }, t.getCurrentPages = function() { var e = []; return x.forEach(function(t) { e.push(t.page) }), e }, M = {}, // 緩存所有已經(jīng)注冊(cè)的頁(yè)面 t.pageHolder = function(e) { if (!__wxRouteBegin) throw (0, f.error)("Page 注冊(cè)錯(cuò)誤", "Please do not register multiple Pages in " + __wxRoute + ".js"), new a.AppServiceEngineKnownError("Please do not register multiple Pages in " + __wxRoute + ".js"); __wxRouteBegin = !1; var t = __wxRoute; if (!A(t)) throw (0, f.error)("Page 注冊(cè)錯(cuò)誤", __wxRoute + " has not been declared in app.json."), new a.AppServiceEngineKnownError(__wxRoute + " has not been declared in app.json."); var n = "undefined" != typeof __wxAppCode__ ? __wxAppCode__[t + ".json"] || {}: {}; if ("Object" !== (0, f.getDataType)(e)) throw (0, f.error)("Page 注冊(cè)錯(cuò)誤", "Options is not object: " + JSON.stringify(e) + " in " + __wxRoute + ".js"), new a.AppServiceEngineKnownError("Options is not object: " + JSON.stringify(e) + " in " + __wxRoute + ".js"); (0, f.info)("Register Page: " + t), void 0 !== n.usingComponents ? (__virtualDOM__.Page(e), M[t] = exparser.Component._list[t]) : M[t] = e },
分析上述代碼,我們可以總結(jié) pageHolder 方法的處理流程如下:
小程序在每加載一個(gè)頁(yè)面前,會(huì)先設(shè)置 __wxRouteBegin = true ,用于標(biāo)記防重;
判斷 __wxRouteBegin 是否為 false ,如果是,則拋出多次調(diào)用 Page 注冊(cè)錯(cuò)誤;
設(shè)置 __wxRouteBegin 為 false ,避免被后續(xù)代碼被重復(fù)執(zhí)行;
調(diào)用 A(...) 方法檢查當(dāng)前頁(yè)面是否在 app.json 中定義,如果沒(méi)有,則拋出錯(cuò)誤;
檢查外部入?yún)ⅲ≒ageOptions)是否為 Object 對(duì)象,如果不是,則拋出錯(cuò)誤;
判斷當(dāng)前頁(yè)面是否使用了自定義組件(對(duì)于使用了自定義組件的 Page 對(duì)象會(huì)采用不同的配置),然后緩存當(dāng)前 Page 的配置到 M 對(duì)象中。
此外,我們可以發(fā)現(xiàn),與 App() 不同的是, 外部通過(guò) Page() 函數(shù)傳入的(生命周期)代碼并不會(huì)在這里被執(zhí)行,而是等待頁(yè)面 Ready 并進(jìn)入頁(yè)面進(jìn)行實(shí)例化后才執(zhí)行。
同樣地,根據(jù) page-frame.html 的加載順序,在 app.js 被加載并執(zhí)行后,小程序之后會(huì)先依次按順序加載所有的自定義組件代碼(如果有)并自動(dòng)注冊(cè)。自定義組件(Component)在小程序開(kāi)發(fā)中具有重要地位,它可以豐富小程序的基礎(chǔ)功能,擁有的能力比