在螞蟻金服的開(kāi)放平臺(tái)上看到一些貼子,說(shuō)提供一個(gè)工具,一鍵轉(zhuǎn)換微信小程序?yàn)橹Ц秾毿〕绦颉N遗c百度的人交流時(shí),也聽(tīng)到相似的東西。其實(shí)都沒(méi)有這么簡(jiǎn)單,它們最多是將一些循環(huán)條件分支指令改一下名,將一些文件的后綴名改一下,更多的差異點(diǎn)在API與各式的配置對(duì)象上,細(xì)節(jié)是魔鬼,我在娜娜奇的官網(wǎng)也列舉了許多相關(guān)的東西,但也不能打票說(shuō)已經(jīng)很齊全。。。。
各種小程序的差異點(diǎn)-文檔
補(bǔ)充一句,娜娜奇是我們公司的小程序開(kāi)發(fā)框架,以React方式轉(zhuǎn)譯成各種小程序與快應(yīng)用的框架。類似于京東的taro。
最近忙于支付寶小程序的開(kāi)發(fā),我得到許多有關(guān)小程序的一手資料,包括自己測(cè)試得到的,及從百度,小米快應(yīng)用與支付寶內(nèi)部人士提供的。
本文將重點(diǎn)說(shuō)一下小程序的組件機(jī)制,之前娜娜奇的組件機(jī)制是基于template標(biāo)簽實(shí)現(xiàn)的,但百度的template有點(diǎn)BUG,給他們提了,不知現(xiàn)在修了沒(méi)有。與template機(jī)制在快應(yīng)用又出入太大,于是轉(zhuǎn)向用自定義組件機(jī)制開(kāi)發(fā)娜娜奇的組件機(jī)制。下面鏈接有一些相關(guān)的測(cè)試與說(shuō)明
轉(zhuǎn)換小程序 · Issue #133 · RubyLouvre/anu
經(jīng)測(cè)試,使用了自定義組件機(jī)制的確是比template實(shí)現(xiàn)的簡(jiǎn)潔一些。但自定義組件機(jī)制是一個(gè)比較高級(jí)的特性,因此兼容性上比template差多了。只能內(nèi)部推到各方改進(jìn)了。
微信在Component的配置對(duì)象提供了一些對(duì)象如methods, lifetimes,pageLifetimes,來(lái)減少其直轄的配置項(xiàng)。
比如說(shuō)lifetimes收納了created、attached、ready、moved、detached這些生命周期鉤子,pageLifetimes收納了onShow, onHide這些與頁(yè)面切換的鉤子,methods收納剩下的方法,另外還有許多配置項(xiàng)。的確,微信小程序獨(dú)自發(fā)布這么久,肯定是最完善的
支付寶的自定義組件機(jī)制沒(méi)有properties,只有props,并且作用也不一樣,props只是指定默認(rèn)值,不是規(guī)定參數(shù)類型。支付寶也沒(méi)有l(wèi)ifetimes與pageLifetimes對(duì)象,生命周期函數(shù)的名字也不一樣 didMount 、didUpdate 、didUnmount,數(shù)量也少了,但從名稱來(lái)看,支付寶在內(nèi)部應(yīng)該運(yùn)行一個(gè)自己的迷你React。
其他方面,支付寶沒(méi)有 dataset, selectComponent,selectAllComponents,getRelationNodes這些東西,但支持了早被React廢棄的mixin機(jī)制。
支付寶沒(méi)有created這樣的鉤子是相當(dāng)麻煩的事,因此積級(jí)推動(dòng)他們加上這個(gè)鉤子!
百度的自定義組件機(jī)制與微信的較為相近,但也沒(méi)有l(wèi)ifetimes與pageLifetimes對(duì)象,只有4種生命周期鉤子:created,attached,ready,detached。有selectComponent,selectAllComponents。
快應(yīng)用的頁(yè)面與組件的配置對(duì)象都是一樣,但它沒(méi)有構(gòu)造函數(shù),只是要求我們export一個(gè)對(duì)象
有props對(duì)象,用來(lái)定義類型與默認(rèn)值,也有與state相似的data對(duì)象,也有三個(gè)做了訪問(wèn)限制的private, protected, public對(duì)象。生命周期鉤子上有onInit、onReady、onDestroy這三個(gè)。
從組件的設(shè)計(jì)來(lái)看, 微信 > 百度 > 支付寶 > 快應(yīng)用
因此想兼容這么多種小程序,我們必須自己寫(xiě)一個(gè)工廠方法,根據(jù)不同的平臺(tái)生成不同的配置項(xiàng),并且放棄掉一些微信的強(qiáng)大功能了。
var hooksName = { wx: ['created', 'attached', 'detached'], bu: ['created', 'attached', 'detached'], ali: ['didMount', 'didMount', 'didUnmount'], quick: ['onInit', 'onReady', 'onDestroy'], }; export function registerComponent(type, name) { registerComponents[name] = type; var reactInstances = (type.reactInstances = []); var wxInstances = (type.wxInstances = []); var hooks = [ function created() { var instance = reactInstances.shift(); if (instance) { console.log('created時(shí)為', name, '添加wx'); instance.wx = this; this.reactInstance = instance; } else { console.log('created時(shí)為', name, '沒(méi)有對(duì)應(yīng)react實(shí)例'); wxInstances.push(this); } }, function attached() { if(appType == "ali"){ created.call(this) } if (this.reactInstance) { updateMiniApp(this.reactInstance); console.log('attached時(shí)更新', name); } else { console.log('attached時(shí)無(wú)法更新', name); } }, function detached() { this.reactInstance = null; }, ]; var data = { props: {}, state: {}, context: {}, }; var config = { data: data, public: data, dispatchEvent: eventSystem.dispatchEvent, methods: { dispatchEvent: eventSystem.dispatchEvent, }, }; hooksName[appType].forEach(function(name, index) { config[name] = hooks[index]; }); return config; } |