A閃:這個(gè)環(huán)節(jié)時(shí)間會(huì)有點(diǎn)長(zhǎng)能颁,分兩個(gè)部分,第一個(gè)是跟大家講一下MINA框架顺饮,所以我們需要花一點(diǎn)時(shí)間講一下整個(gè)微信小程序MINA實(shí)現(xiàn)原理吵聪。第二個(gè)是DEMO。
我們說(shuō)一下MINA框架兼雄,MINA框架里做了很多設(shè)計(jì)吟逝,這個(gè)設(shè)計(jì)有一部分對(duì)接到了原生實(shí)現(xiàn)的那一層上面。在PC端上做開(kāi)發(fā)的時(shí)候赦肋,大家用官方ID跑的MINA和我們最終移動(dòng)端跑的效果會(huì)有差異块攒,差異主要在兩個(gè)方面,第一個(gè)是UI渲染以后效果會(huì)不太一樣佃乘。同時(shí)囱井,流暢度會(huì)有一些不太一樣的地方。首先來(lái)看一下框架的特點(diǎn)趣避。它做了一個(gè)數(shù)據(jù)綁定庞呕,我們一開(kāi)始說(shuō)過(guò)為什么做微信的產(chǎn)品不要用網(wǎng)頁(yè)開(kāi)發(fā)的思路,你要通過(guò)數(shù)據(jù)刷新催生試圖發(fā)生變化程帕,而不是用直接手動(dòng)的去操作試圖住练,這個(gè)是沒(méi)有的,也不能做到愁拭。為什么不能做到讲逛,因?yàn)樗讓拥膶?shí)現(xiàn)方法,在講邊緣的時(shí)候也會(huì)講到岭埠。第二個(gè)是頁(yè)面管理盏混,頁(yè)面管理涉及到生命周期的問(wèn)題蔚鸥,這也是在MINA做了很多工作。第三個(gè)是組件與API许赃,
在一個(gè)微信小程序里面止喷,我們有一個(gè)APP接口和多個(gè)page組成,每一個(gè)程序之間切換都是在翻頁(yè)图焰。APP這個(gè)是整個(gè)微信小程序一個(gè)入口启盛,這個(gè)入口包含三個(gè)文件,第一個(gè)文件是它的入口文件所有微信小程序其中的入口技羔,也就是尋找你啟動(dòng)入口全部要從APP進(jìn)入。第二個(gè)是page文件卧抗,有幾個(gè)比較關(guān)鍵的藤滥,比如我們頁(yè)面注冊(cè),為什么會(huì)有這個(gè)過(guò)程社裆,是因?yàn)楹蚆INA底層設(shè)計(jì)的結(jié)構(gòu)拙绊、形式有關(guān)系。第三個(gè)是公共樣式表泳秀,內(nèi)置的組件都可以通過(guò)公共樣式表來(lái)設(shè)定标沪。
page一共有四個(gè)文件,第一個(gè)是page的js文件嗜傅,第二個(gè)是whml金句,頁(yè)面界面渲染部分。第三個(gè)是wxss頁(yè)面樣式表吕嘀,第四個(gè)是json頁(yè)面配置违寞。這個(gè)頁(yè)面配置的文件很少用到。
我們來(lái)看一下MINA兩層架構(gòu)偶房,一個(gè)是試圖層—一個(gè)是邏輯層趁曼。在整個(gè)程序編輯或者運(yùn)行的時(shí)候是由兩個(gè)主線來(lái)渲染∽匮螅框架的試圖層由Wxml與wxss編寫挡闰,由組件來(lái)進(jìn)行展示。將邏輯層的數(shù)據(jù)反應(yīng)城市土掰盘,同時(shí)將試圖層的事件發(fā)送給邏輯層摄悯。試圖層是負(fù)責(zé)頁(yè)面的渲染。邏輯層就比較簡(jiǎn)單庆杜,因?yàn)樗x了我們框架由js來(lái)編寫射众,同時(shí)負(fù)責(zé)了數(shù)據(jù)的整理,由javoscrip而編寫晃财,邏輯層將數(shù)據(jù)進(jìn)行處理后發(fā)送給試圖層叨橱,同時(shí)接受試圖層的事件反饋典蜕。增加APP五和page為方法,進(jìn)行程序和頁(yè)面的注冊(cè)罗洗。提供豐富的API愉舔,如掃一掃,支持等微信特有能力伙菜。每個(gè)頁(yè)面有獨(dú)立的作用域轩缤,并提供模塊化能力,框架并非運(yùn)行在瀏覽器中贩绕。怎么實(shí)現(xiàn)從一個(gè)配置到另一個(gè)配置可以發(fā)送一些數(shù)據(jù)火的,默認(rèn)發(fā)送的數(shù)據(jù)非常有限,我們可以借助其他方法實(shí)現(xiàn)淑倾。
生命周期馏鹤,這個(gè)是整個(gè)MINA框架生命周期的圖(PPT)左邊綠色是試圖層,是做渲染的娇哆,右側(cè)是app湃累,做邏輯渲染。首先當(dāng)我們這個(gè)小程序旺起來(lái)以后碍讨,微信會(huì)把兩個(gè)線全部弧起來(lái)治力,從入口開(kāi)始,執(zhí)行start勃黍。試圖層會(huì)根據(jù)你填寫的那一段的參數(shù)宵统,配置的內(nèi)容去尋找到底哪個(gè)頁(yè)面能夠渲染,所以會(huì)做初始化溉躲。初始化完成以后榜田,這個(gè)會(huì)給邏輯層發(fā)一個(gè)消息,一個(gè)通知锻梳,我所有的初始化完成箭券,這個(gè)線就暫停了,它的任務(wù)完成了疑枯。邏輯層一開(kāi)始是支持ready辩块,所以它會(huì)執(zhí)行一個(gè)創(chuàng)建,創(chuàng)建完以后荆永,他也暫停废亭。暫停以后,可以進(jìn)行初始化代碼具钥,請(qǐng)求去訪問(wèn)一些需要默認(rèn)和用到的數(shù)據(jù)豆村。在onload作完以后,會(huì)拋一個(gè)onshow的方法骂删,表示這個(gè)頁(yè)面要進(jìn)行創(chuàng)建操作了掌动。onshow完以后四啰,要有一些數(shù)據(jù),這個(gè)時(shí)候怎么做粗恢?我們會(huì)直接調(diào)用sendinifialData方法柑晒。我的試圖第一次渲染完成,這個(gè)界面就完成了眷射。onready才能保證你的數(shù)據(jù)在第一頻是完整的匙赞,這個(gè)是最開(kāi)始的初始化的過(guò)程。
一直到onseady之后妖碉,兩邊都不運(yùn)行了涌庭,然后這個(gè)畫面就禁止在這里。業(yè)務(wù)邏輯層當(dāng)你做完這邊的進(jìn)程才會(huì)進(jìn)入到一個(gè)激活的狀態(tài)欧宜,你可以做其他業(yè)務(wù)邏輯運(yùn)算脾猛,后面就比較常規(guī),當(dāng)用戶或者你的業(yè)務(wù)邏輯做了運(yùn)算之后鱼鸠,運(yùn)算結(jié)果通過(guò)data發(fā)給試圖層,接收之后再渲染一次羹铅。如果用戶觸摸屏幕了蚀狰,從試圖層會(huì)往邏輯層發(fā)一個(gè)消息通知,這個(gè)消息通知里還包含一些交互的數(shù)據(jù)职员,比如說(shuō)麻蹋,擬稿點(diǎn)了那個(gè)按紐,這個(gè)按紐的IP是多少焊切,冒泡的層級(jí)是多少扮授,都會(huì)發(fā)送數(shù)據(jù)。從生命周期的流程圖可以看到专肪,想用js直接操控試圖界面的是完全做不到刹勃,你只能通過(guò)數(shù)據(jù)更新的方式去刷新我們右側(cè)的試圖層,所以是一個(gè)被動(dòng)模式嚎尤。
當(dāng)我們小程序用完了之后荔仁,用戶點(diǎn)了返回,進(jìn)入到聊天界面芽死,這個(gè)程序還沒(méi)有完畢乏梁,就進(jìn)入到后臺(tái)的狀態(tài)。我們業(yè)務(wù)邏輯層依然會(huì)給你回一個(gè)函數(shù)关贵,你能知道這個(gè)界面當(dāng)前被暫停了遇骑,暫停之后不消耗任何內(nèi)存。我們兩邊的都會(huì)被暫停運(yùn)算揖曾。當(dāng)我們回到微信小程序里落萎,當(dāng)你的業(yè)務(wù)程序還沒(méi)有被真正的殺死亥啦,它的就要會(huì)回到前臺(tái)的位置,重新回到激活狀態(tài)模暗,回到激活狀態(tài)禁悠,既然激活了試圖層真正渲染的現(xiàn)場(chǎng),所以這邊我們會(huì)調(diào)一個(gè)onshow兑宇,當(dāng)你得到通知以后碍侦,你的頁(yè)面又展示出來(lái),處于激活狀態(tài)隶糕,你就可以把操作返回回去瓷产。什么時(shí)候這個(gè)程序真正被殺死?這里面有一些api枚驻,你可以選擇主動(dòng)退出小程序或者業(yè)務(wù)程序退出以后濒旦,用戶隔了很長(zhǎng)時(shí)間沒(méi)有進(jìn)入之后,這個(gè)才會(huì)真正被微信干掉再登,也會(huì)給你回一個(gè)函數(shù)尔邓。這需要做一個(gè)非常關(guān)鍵的操作,把你存儲(chǔ)到當(dāng)?shù)氐臄?shù)據(jù)通過(guò)api把數(shù)據(jù)全部存進(jìn)去锉矢,這樣下次進(jìn)來(lái)數(shù)據(jù)還在梯嗽。同時(shí),做一些清空銷毀作用沽损,你需要給服務(wù)器發(fā)一個(gè)包灯节,用戶什么時(shí)候進(jìn)行了退出。這樣才會(huì)被真正干掉绵估,這個(gè)小程序就真的不存在了炎疆。
這個(gè)是整個(gè)微信小程序的生命周期的過(guò)程。很簡(jiǎn)單国裳,大家只要注意幾個(gè)方法就可以了形入。
在這個(gè)生命周期講完以后躏救,我們來(lái)看一下編譯項(xiàng)目崩掘。編譯文件當(dāng)中做了什么英妓,我們通過(guò)這個(gè)就能大致知道在編寫項(xiàng)目的時(shí)候能有什么坑吗蚌,會(huì)出現(xiàn)什么問(wèn)題。第一個(gè)創(chuàng)建頁(yè)面會(huì)轉(zhuǎn)換javascript焕襟,編譯whml。
第一個(gè)創(chuàng)建頁(yè)面。這個(gè)創(chuàng)建頁(yè)面是干什么镐确,在小程序入口還是一個(gè)網(wǎng)頁(yè)息堂,那個(gè)頁(yè)面里是一個(gè)默認(rèn)的模板振坚,這個(gè)文件才是我們真正界面的文件,你也不用編譯渡八,編譯的時(shí)候就把這個(gè)文件塞進(jìn)去了啃洋。
第二步是編一個(gè)jovascript传货,在編譯過(guò)程中除了自己的代碼還會(huì)注入非常多的東西,這些東西都跟MINA框架有關(guān)系宏娄。這個(gè)是js的編譯问裕。
第三步是編譯這兩個(gè)文件就比較有意思,WHML/WXSS孵坚,不知道里面干了什么粮宛,反正看起來(lái)很亂,這個(gè)在試圖層真正運(yùn)行起來(lái)的時(shí)候會(huì)執(zhí)行JS文件十饥,然后把塞在文件里面窟勃。
這三個(gè)動(dòng)作編譯完成以后,最終就是編譯過(guò)程逗堵,三步秉氧。
關(guān)于MINA的框架,就介紹到這里蜒秤。
嘉賓:我想問(wèn)一下汁咏,編譯是在哪里完成?
A閃:編譯是在開(kāi)發(fā)工具里作媚,編譯過(guò)程跑完以后會(huì)打一個(gè)包攘滩,就可以上傳到微信服務(wù)器。
嘉賓:在生命周期的時(shí)候纸泡,不是有一個(gè)時(shí)間段漂问,但是我們?cè)谶@個(gè)階段我們有時(shí)候需要根據(jù)API做結(jié)合,比如我們做一個(gè)組件的時(shí)候女揭,我們要測(cè)定播放狀態(tài)蚤假,我們需要獲取密碼,我們會(huì)發(fā)現(xiàn)最終編譯的時(shí)候會(huì)把play的方法先播放吧兔,再完成這個(gè)Setdata過(guò)程磷仰,這個(gè)過(guò)程并不是我想要的。這個(gè)有沒(méi)有解決方案境蔼?很多都要結(jié)合API來(lái)做灶平,我們要刷新就只有通過(guò)setdata來(lái)。
A閃:音頻渲染是在試圖上跑的箍土,很難及時(shí)的去獲取這個(gè)狀態(tài)逢享,獲取了以后也是通過(guò)編碼才能看到現(xiàn)在是播到那一秒,這中間會(huì)有一個(gè)小的延時(shí)吴藻,這個(gè)是機(jī)制問(wèn)題拼苍,沒(méi)有太好的解決方案。
嘉賓:我發(fā)現(xiàn)組件我們不能自定義控制樣式,我通過(guò)去查找動(dòng)畫原理來(lái)寫了一下疮鲫,我發(fā)現(xiàn)控制樣式的時(shí)候吆你,這個(gè)過(guò)程是很不順暢的。
A閃:在更新的時(shí)候去鎖一下用戶的交互俊犯,然后再畫妇多。
嘉賓:這樣我就沒(méi)有辦法做到我慢慢滑動(dòng)的時(shí)候,第二屏就可以實(shí)時(shí)進(jìn)入到我們的視野當(dāng)中燕侠。
A閃:我們下來(lái)再討論者祖。從試圖上來(lái)講,渲染應(yīng)該不會(huì)很慢绢彤,但是你的業(yè)務(wù)邏輯操作會(huì)很慢七问,如果卡頓也有可能是結(jié)果計(jì)算有問(wèn)題,就像我們做游戲一樣茫舶。
嘉賓:我們?cè)谠O(shè)置標(biāo)題的時(shí)候械巡,我發(fā)現(xiàn)在IP的時(shí)候,我在編譯Js的時(shí)候可以實(shí)時(shí)顯示我們的標(biāo)題饶氏,但是一保存這個(gè)標(biāo)題讥耗,就變成我在js配置的標(biāo)題。
我們這個(gè)生命周期下來(lái)疹启,我們通常有一些數(shù)據(jù)是要在onshow還是什么上處理古程?
A閃:跟你自己的需求有關(guān)系,沒(méi)有說(shuō)必須要放在哪里設(shè)定喊崖,看你想實(shí)現(xiàn)什么效果挣磨。
A閃:我們先來(lái)看一下這個(gè)東西。我有一個(gè)官方的DEMO荤懂,如果我們現(xiàn)在已經(jīng)申請(qǐng)到了APP和ID的話趋急,這個(gè)做完之后就可以直接做。我們下面有一個(gè)預(yù)覽和上傳势誊,我們點(diǎn)預(yù)覽的時(shí)候會(huì)把本地的代碼直接打包,推到服務(wù)器谣蠢。這個(gè)代碼別人掃就沒(méi)有用了粟耻,只要在后臺(tái)綁定了,只有管理者才能看到眉踱。
中間還有一個(gè)longing的過(guò)程挤忙,上面有一個(gè)返回按紐,你只要一點(diǎn)就直接退出了谈喳,和PC上預(yù)覽效果是有差異的册烈。
我們來(lái)看一下,這個(gè)是在PC上的預(yù)覽,在真機(jī)上的樣式就完全不對(duì)赏僧。PC端點(diǎn)開(kāi)就這樣(PPT)大猛,最好在真機(jī)上測(cè)。在我們右上角淀零,這個(gè)是DEMO版本挽绩,正式發(fā)布的時(shí)候會(huì)有一些東西沒(méi)有的。這邊是當(dāng)前用戶的APP的名稱驾中,頁(yè)面里沒(méi)有正式發(fā)布唉堪。你可以將這個(gè)東西分享給你的好友。最后會(huì)有一個(gè)分享功能肩民,能把這個(gè)分享給你的好友唠亚。但是這個(gè)功能上一周還有,這一周已經(jīng)沒(méi)有了持痰。大家可以去申一個(gè)號(hào)去看看灶搜。
需要說(shuō)一點(diǎn)的是,大家在做的時(shí)候肯定會(huì)訪問(wèn)自己的服務(wù)器共啃,有一些網(wǎng)絡(luò)功能占调,網(wǎng)絡(luò)的訪問(wèn)必須是ISS加密的,普通的未加密的訪問(wèn)在真機(jī)上根本就跑不了移剪,全部會(huì)錯(cuò)究珊,會(huì)告訴你是非法訪問(wèn),全部是不合格的纵苛。iss加密證書(shū)也比較有意思剿涮,原來(lái)有很多面的證書(shū),最起碼能用一年攻人。但是現(xiàn)在瀏覽器把這個(gè)證書(shū)加密的規(guī)則改了取试,現(xiàn)在免費(fèi)的證書(shū)基本上都不能用了,都只能加付費(fèi)的證書(shū)才能使用怀吻,這個(gè)是很大的問(wèn)題瞬浓。服務(wù)器搭建的時(shí)候一定要把非加密的證書(shū)清楚掉。
如果現(xiàn)在手里有電腦的話這個(gè)DEMO也能打開(kāi)蓬坡,我們用自己的工具猿棉,我們來(lái)看一下具體的代碼。這個(gè)是程序入口屑咳,在開(kāi)之前我們先點(diǎn)一下調(diào)試運(yùn)行萨赁,這個(gè)是官方工具的調(diào)試模塊,在這里直接能看兆龙。這個(gè)功能比較簡(jiǎn)單杖爽,我們來(lái)看一下交互,默認(rèn)的這個(gè)面板里面是我們國(guó)家貨幣的兌換,有一個(gè)基準(zhǔn)慰安,默認(rèn)我們用第一個(gè)腋寨。下面我們做一個(gè)軟鍵盤,點(diǎn)美元然后點(diǎn)8泻帮,下面四個(gè)就會(huì)跟隨著精置,進(jìn)行實(shí)時(shí)的數(shù)據(jù)切換。如果切換到港幣锣杂,點(diǎn)9糜俗,就會(huì)進(jìn)行匯率換算渔扎。默認(rèn)五個(gè)國(guó)家的貨幣信息全部是從服務(wù)器拉下來(lái)的,我們把這個(gè)格式自己組裝一下,當(dāng)切換一下貨幣就會(huì)進(jìn)入到一個(gè)國(guó)旗藏鹊。
文本輸入方式我們選擇了組件以后昼激,定義成焦點(diǎn)汁汗,然后刷新內(nèi)容咪辱,用這個(gè)方式來(lái)實(shí)現(xiàn),這個(gè)是唯一可行性的方案茎截。
我們來(lái)看一下入口苇侵,JS這個(gè)文件可以在里面進(jìn)行操作,在onshow寫一些內(nèi)容企锌,做一些還原操作也可以進(jìn)行操作榆浓。真正非常敏感想在服務(wù)器獲取客戶信息的時(shí)候都沒(méi)有,只有頭像撕攒、名稱陡鹃、年齡還有所在地區(qū)。我們這個(gè)DEMO需要幾個(gè)重要的數(shù)據(jù)抖坪,我們?cè)贏PP上定義了四個(gè)變量萍鲸,這四個(gè)變量后面還會(huì)用到,有城市ID擦俐,有城市的列表脊阴,我們把列表數(shù)據(jù)也放在這里。當(dāng)我們進(jìn)行國(guó)家貨幣切換的時(shí)候也放在這個(gè)里面蚯瞧,我們會(huì)放一些數(shù)據(jù)嘿期。
這個(gè)文件我們里看一下Js文件,這里面有一個(gè)配置標(biāo)志状知,這就需要能夠把顯示參與渲染的界面全部寫進(jìn)去,沒(méi)有寫進(jìn)去以后就不能調(diào)取孽查。這個(gè)東西被讀取后期就改不了了饥悴。
每一個(gè)頁(yè)面都是配置項(xiàng),配置里面有一個(gè)默認(rèn)的setdata,這里面可以自己設(shè)定當(dāng)前頁(yè)面數(shù)據(jù)西设,對(duì)外不可識(shí)別瓣铣,不可讀。我們不光想讓默認(rèn)的頁(yè)面渲染去讀它贷揽,可以把DATA的數(shù)據(jù)取出來(lái)塞在試圖層里面棠笑。
我們來(lái)看一下一開(kāi)始在程序運(yùn)行的時(shí)候,當(dāng)?shù)谝粋€(gè)頁(yè)面初始化以后禽绪,我們會(huì)調(diào)用onlow的方法蓖救,我們從服務(wù)器獲取了一些國(guó)家默認(rèn)的信息,這里面的獲取我們?nèi)堪褬I(yè)務(wù)邏輯放在一個(gè)模塊里印屁,這個(gè)模塊是我們自定義的第三方模塊循捺。你的業(yè)務(wù)程序會(huì)有很多這樣的模塊。
原數(shù)據(jù)取出來(lái)雄人,按照我們需要的格式塞進(jìn)去从橘,這些塞進(jìn)去默認(rèn)前五個(gè)國(guó)家的信息都有了以后,我們?cè)谙旅嬷苯诱{(diào)用這個(gè)Setwdata础钠。
我們點(diǎn)擊國(guó)家圖片或者文字的時(shí)候會(huì)有一個(gè)事件傳遞恰力,后面會(huì)有一個(gè)標(biāo)記,這就傳入了方法名稱旗吁,這個(gè)方法名稱要在當(dāng)前的js里面定義踩萎,它的傳遞方式也是一樣,本身是一個(gè)字符串阵漏,是一個(gè)標(biāo)記驻民,從試圖層向邏輯層傳遞的時(shí)候會(huì)有一個(gè)過(guò)程。
我們每次修改數(shù)字或者是前數(shù)以后都會(huì)執(zhí)行setdata履怯,因?yàn)樗捏w積非常小回还,只有五項(xiàng)。當(dāng)點(diǎn)擊一個(gè)國(guó)家的時(shí)候我們要對(duì)國(guó)家進(jìn)行跳轉(zhuǎn)叹洲,這個(gè)時(shí)候執(zhí)行頁(yè)面跳轉(zhuǎn)柠硕,跳轉(zhuǎn)我們還需要執(zhí)行一個(gè)非常重要的信息。
參數(shù)數(shù)據(jù)不能太大运提,傳一個(gè)ID或者是一個(gè)標(biāo)記一個(gè)操作都可以蝗柔,如果傳的數(shù)據(jù)量比較大的話,麻煩就大了民泵。
在我們國(guó)家列表頁(yè)面里面癣丧,我們要把選中的國(guó)家數(shù)據(jù)會(huì)傳,這個(gè)方式就比較復(fù)雜了栈妆。我們的做法是胁编,我們?cè)谶@個(gè)頁(yè)面JS厢钧,當(dāng)我們選擇一個(gè)國(guó)家之后,我們先走一遍網(wǎng)絡(luò)嬉橙,把這個(gè)國(guó)家的匯率先取回來(lái)早直,取回來(lái)之后,這個(gè)時(shí)候直接就跳轉(zhuǎn)到那個(gè)頁(yè)面市框。
詳情請(qǐng)見(jiàn):http://bbs.larkapp.com/thread-11903-1-1.html